v0.248.0: i18n slice 1 release A — apps and settings in English, Hungarian byte-identical (R-556)
gates / gates (push) Successful in 20s
gates / gates (push) Successful in 20s
Ten pages converted against fixtures captured from unconverted templates (6be55a0); marker
coverage test; English page mask narrowed; English retrieval-promise stems; common keys;
title keys and infraMeta from the bundle; old wording tests read the Hungarian expansion.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -1,3 +1,46 @@
|
|||||||
|
## v0.248.0 — English for apps and settings: ten more pages, Hungarian byte-identical (2026-09-17, R-556 release A)
|
||||||
|
|
||||||
|
**MinAgent: 0.131.0** (unchanged). **No hub release needed.** Nothing changes for a Hungarian household:
|
||||||
|
the switch is still shown only on English pages (decision 6 stands until release C).
|
||||||
|
|
||||||
|
- **Converted:** `dashboard`, `stacks`, `logs`, `monitoring`, `app_import`, `app_export`, `deploy`,
|
||||||
|
`settings_system`, `settings_security`, `settings_notifications` (572 markers). `app_row`,
|
||||||
|
`meta_badge`, `icons` carry no copy (verified). 16 repeated strings now share `common.*` keys
|
||||||
|
where the meaning is the same everywhere; „Mentés" (Save/Backup), „Frissítés" (Update/Refresh),
|
||||||
|
„Indítás" (Start/Boot) deliberately stay per page.
|
||||||
|
- **Parity:** 25 new fixture states captured from the UNCONVERTED templates (commit `6be55a0`) before
|
||||||
|
any of these pages carried a marker. Five v0.247.0 fixtures were re-captured from v0.246.0
|
||||||
|
(`89dd3e94`) because their one-word Hungarian data had to become multi-word (below).
|
||||||
|
- **New test — `TestI18nParityCoversEveryMarker`:** every marker occurrence must be rendered by some
|
||||||
|
parity case. It found two gaps in v0.247.0's own pages (the app page's Install button; one „Due"
|
||||||
|
tag), closed with two new cases captured from v0.246.0.
|
||||||
|
- **English page test widened:** only fixture strings of 2+ words or 12+ characters are masked; titles
|
||||||
|
go through `addLanguageData`. Measured: with one English nav key deleted, the old test flagged 8
|
||||||
|
cases and missed the 6 launcher cases; the new one flags all 14.
|
||||||
|
- **Retrieval-promise gate reads English** (`EN_PATTERNS`, `ALLOWLIST_EN`): HEAD passed a planted
|
||||||
|
„Your old backups can be restored at any time." in `en.json`; the gate now convicts it and accepts the
|
||||||
|
same place carrying a sentence that promises nothing. Decoys in `test_gate_decoys.py`.
|
||||||
|
- **Go-side copy on these pages:** titles via `TitleKey` (dashboard, stacks, monitoring, the three
|
||||||
|
settings pages); `infraMeta` descriptions (and samba's name) from the bundle, Hungarian pinned equal
|
||||||
|
to `inframeta.go`.
|
||||||
|
- **Found, not converted:** `backups_remote.html` decides with `indexOf('Fut')` against its own
|
||||||
|
Hungarian status text (row filed); converting that word would silently break the English page's
|
||||||
|
progress poll. Composite page titles (logs, deploy, export) and `lifecycleBadge`/`updateBadge`
|
||||||
|
remain Hungarian — slice 2.
|
||||||
|
- **Extractor:** ASCII-only Hungarian it missed on these pages — Mind, Folyamat, Titkos, Processzor,
|
||||||
|
Hamarosan, aldomain, „Az adatai itt voltak", Figyelem, pelda@email.hu — converted by hand; words added
|
||||||
|
to its list (not „Mind": an English homograph). It also learnt that a JS string can start inside an
|
||||||
|
attribute value.
|
||||||
|
- `HU_FORMAL_CEILING` 6 → 10: the converted copy carries four more „ön" forms (R-516), unchanged by rule.
|
||||||
|
- Old wording tests (`TestDiskMeter_*`, `TestNetworkBadgeTemplates_DistinctStrings`,
|
||||||
|
`TestSettingsSectionInventory`) read the Hungarian expansion (`huTemplateSource`), not the raw file.
|
||||||
|
- `loadTemplates` logs its parse duration per language (DEBUG).
|
||||||
|
|
||||||
|
**Red-proofs** (`felhom.eu/documentation/audits/i18n-slice1-2026-09-17/A/redproofs.txt`): parity (one byte
|
||||||
|
of `dashboard.lemezek_allapota` → 4 dashboard cases name line and bytes); coverage (a marker in an
|
||||||
|
unreachable launcher branch → named, while parity stayed green); mask widening (8 vs 14 cases);
|
||||||
|
retrieval gate (HEAD rc 0 on the planted promise → fixed gate convicts, negative control accepted).
|
||||||
|
|
||||||
## v0.247.0 — the dashboard can speak English: mechanism proven on three pages, Hungarian byte-identical (2026-09-17, i18n spike)
|
## v0.247.0 — the dashboard can speak English: mechanism proven on three pages, Hungarian byte-identical (2026-09-17, i18n spike)
|
||||||
|
|
||||||
**MinAgent: 0.131.0** (unchanged — nothing here talks to the agent). **No hub release needed:** the
|
**MinAgent: 0.131.0** (unchanged — nothing here talks to the agent). **No hub release needed:** the
|
||||||
|
|||||||
@@ -231,6 +231,7 @@
|
|||||||
| `getBudapestLocation` | controller/internal/scheduler/scheduler.go | `() *time.Location` | Local-time math | web has its own `getTimezone` (§6); quiesce has its own `budapestLocation` (window gate) — 3rd copy, see §6 |
|
| `getBudapestLocation` | controller/internal/scheduler/scheduler.go | `() *time.Location` | Local-time math | web has its own `getTimezone` (§6); quiesce has its own `budapestLocation` (window gate) — 3rd copy, see §6 |
|
||||||
| `Server.templateFuncMap` | controller/internal/web/funcmap.go | template.FuncMap | ALL template functions | `stateColor` outputs v2 suffixes `run/progress/warn/neutral/off`; stopped = NEUTRAL not red (operator-approved); `stateLabel` copy is frozen byte-identical (unit-tested) |
|
| `Server.templateFuncMap` | controller/internal/web/funcmap.go | template.FuncMap | ALL template functions | `stateColor` outputs v2 suffixes `run/progress/warn/neutral/off`; stopped = NEUTRAL not red (operator-approved); `stateLabel` copy is frozen byte-identical (unit-tested) |
|
||||||
| `i18n.Bundle` (`Shared` / `Msg` / `Plural` / `Expand`) | controller/internal/i18n/i18n.go | `Msg(lang, key) string` | ALL customer copy that has been converted (v0.247.0) | hu.json is authoritative; a key missing in en shows Hungarian (counted), never blank; `Expand` runs BEFORE template parse — never add a runtime `T` func (escaping would change Hungarian bytes). A template edit to converted copy goes in hu.json + en.json, then `TestI18nParity` must still pass |
|
| `i18n.Bundle` (`Shared` / `Msg` / `Plural` / `Expand`) | controller/internal/i18n/i18n.go | `Msg(lang, key) string` | ALL customer copy that has been converted (v0.247.0) | hu.json is authoritative; a key missing in en shows Hungarian (counted), never blank; `Expand` runs BEFORE template parse — never add a runtime `T` func (escaping would change Hungarian bytes). A template edit to converted copy goes in hu.json + en.json, then `TestI18nParity` must still pass |
|
||||||
|
| `huTemplateSource` (test) | controller/internal/web/i18n_wiring_test.go | `(name) ([]byte, error)` | A test that asserts a template's Hungarian WORDING | Reads the expansion, not the raw file — since slice 1 the wording lives in hu.json. Never use `templateFS.ReadFile` for a wording assertion |
|
||||||
| `Server.langFor` / `templatesFor` / `addLanguageData` | controller/internal/web/server.go + i18n_web.go | request → lang → template set | Rendering a page in the household's language | Only `executeTemplate` is language-aware; `s.tmpl` is the Hungarian set; Go-side titles via `data["TitleKey"]` |
|
| `Server.langFor` / `templatesFor` / `addLanguageData` | controller/internal/web/server.go + i18n_web.go | request → lang → template set | Rendering a page in the household's language | Only `executeTemplate` is language-aware; `s.tmpl` is the Hungarian set; Go-side titles via `data["TitleKey"]` |
|
||||||
| `timeAgoStr` | controller/internal/web/funcmap.go | `(s RFC3339 string) string` | Ago-format for STRING timestamps | Exists because `timeAgo(time.Time)` 500'd on strings (v0.93 bug) |
|
| `timeAgoStr` | controller/internal/web/funcmap.go | `(s RFC3339 string) string` | Ago-format for STRING timestamps | Exists because `timeAgo(time.Time)` 500'd on strings (v0.93 bug) |
|
||||||
| `Server.baseData` / `executeTemplate` | controller/internal/web/handlers.go + server.go | page-data plumbing | New pages | baseData injects nav/alerts/version; templates must pass `controller/scripts/template_id_gate.py` + `controller/scripts/emoji_gate.py` |
|
| `Server.baseData` / `executeTemplate` | controller/internal/web/handlers.go + server.go | page-data plumbing | New pages | baseData injects nav/alerts/version; templates must pass `controller/scripts/template_id_gate.py` + `controller/scripts/emoji_gate.py` |
|
||||||
|
|||||||
@@ -3621,8 +3621,10 @@ Design: `felhom.eu/documentation/architecture/10-localisation.md`. Inventory:
|
|||||||
|
|
||||||
**What a household sees:** nothing new. Hungarian is the default and the only language shown unless
|
**What a household sees:** nothing new. Hungarian is the default and the only language shown unless
|
||||||
the language is switched. English covers the **launcher**, the **backups overview** (`/backups`), the
|
the language is switched. English covers the **launcher**, the **backups overview** (`/backups`), the
|
||||||
**app page** (`/apps/<slug>`) and the shared **layout** (menu, banners, the layout's modals) — other
|
**app page** (`/apps/<slug>`), the shared **layout**, and since v0.248.0 the **dashboard, apps list,
|
||||||
pages keep their Hungarian body inside an English menu.
|
logs, monitoring, import, export, deploy/settings-of-an-app and the three settings pages** — other
|
||||||
|
pages keep their Hungarian body inside an English menu. Server-built messages and catalog copy stay
|
||||||
|
Hungarian (slices 2 and 5).
|
||||||
|
|
||||||
- **Bundles:** `internal/i18n/locales/hu.json` (authoritative, every key) and `en.json`, embedded.
|
- **Bundles:** `internal/i18n/locales/hu.json` (authoritative, every key) and `en.json`, embedded.
|
||||||
Flat `key → text`; a value may carry template actions (`{{.RecoveryAbandonDate}}`) and inline
|
Flat `key → text`; a value may carry template actions (`{{.RecoveryAbandonDate}}`) and inline
|
||||||
@@ -3650,7 +3652,9 @@ pages keep their Hungarian body inside an English menu.
|
|||||||
exist, no orphans, the English gap and the formal „ön" count only shrink (ratchets), no pleading
|
exist, no orphans, the English gap and the formal „ön" count only shrink (ratchets), no pleading
|
||||||
English. The emoji, native-confirm, secret-in-markup and retrieval-promise gates read templates
|
English. The emoji, native-confirm, secret-in-markup and retrieval-promise gates read templates
|
||||||
**expanded** through `scripts/i18n_bundle.py`; mojibake scans the bundles.
|
**expanded** through `scripts/i18n_bundle.py`; mojibake scans the bundles.
|
||||||
- **Release gate:** `TestI18nParity` compares the Hungarian render of 14 fixture states with HTML
|
- **Coverage:** `TestI18nParityCoversEveryMarker` fails when any marker occurrence is rendered by no
|
||||||
|
parity case. Fixtures are written only when missing (`-update-i18n-golden`, `-i18n-golden-only`).
|
||||||
|
- **Release gate:** `TestI18nParity` compares the Hungarian render of every fixture state with HTML
|
||||||
captured from the unconverted templates (`internal/web/testdata/i18n_parity/`). Fixtures are never
|
captured from the unconverted templates (`internal/web/testdata/i18n_parity/`). Fixtures are never
|
||||||
regenerated to make a conversion pass.
|
regenerated to make a conversion pass.
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,9 @@ func TestEmbeddedBundles(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fieldRefRe = regexp.MustCompile(`\.[A-Z][A-Za-z0-9_]*(\.[A-Z][A-Za-z0-9_]*)*`)
|
var fieldRefRe = regexp.MustCompile(`\.[A-Z][A-Za-z0-9_]*(\.[A-Z][A-Za-z0-9_]*)*`)
|
||||||
var verbRe = regexp.MustCompile(`%[-+# 0-9.]*[sdvq]`)
|
// verbRe counts printf verbs OUTSIDE template actions ({{printf "%.0f" .X}} is a parameter, not a verb
|
||||||
|
// of the message), and without the space flag — „50% szabad" is prose, not „% s".
|
||||||
|
var verbRe = regexp.MustCompile(`%[-+#0-9.]*[sdvq]`)
|
||||||
|
|
||||||
func refs(s string) []string {
|
func refs(s string) []string {
|
||||||
var out []string
|
var out []string
|
||||||
@@ -153,10 +155,12 @@ func TestBundleParametersMatchAcrossLanguages(t *testing.T) {
|
|||||||
if a, c := strings.Join(refs(hu), ","), strings.Join(refs(v), ","); a != c {
|
if a, c := strings.Join(refs(hu), ","), strings.Join(refs(v), ","); a != c {
|
||||||
t.Errorf("%s %q: template fields %q, Hungarian has %q", lang, f, c, a)
|
t.Errorf("%s %q: template fields %q, Hungarian has %q", lang, f, c, a)
|
||||||
}
|
}
|
||||||
if a, c := len(verbRe.FindAllString(hu, -1)), len(verbRe.FindAllString(v, -1)); a != c {
|
if a, c := len(verbRe.FindAllString(stripActions(hu), -1)), len(verbRe.FindAllString(stripActions(v), -1)); a != c {
|
||||||
t.Errorf("%s %q: %d printf verbs, Hungarian has %d", lang, f, c, a)
|
t.Errorf("%s %q: %d printf verbs, Hungarian has %d", lang, f, c, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stripActions(s string) string { return regexp.MustCompile(`\{\{.*?\}\}`).ReplaceAllString(s, "") }
|
||||||
|
|||||||
@@ -1,4 +1,20 @@
|
|||||||
{
|
{
|
||||||
|
"common.bezaras": "Close",
|
||||||
|
"common.elavult": "Outdated",
|
||||||
|
"common.eltavolitas": "Remove",
|
||||||
|
"common.hdd_szukseges": "Needs a hard drive",
|
||||||
|
"common.hiba": "Error",
|
||||||
|
"common.hiba_kettospont": "Error:",
|
||||||
|
"common.hiba_tortent": "An error occurred",
|
||||||
|
"common.jelszo": "Password",
|
||||||
|
"common.levalasztva": "Disconnected",
|
||||||
|
"common.magyar_felulet": "Hungarian interface",
|
||||||
|
"common.megsem": "Cancel",
|
||||||
|
"common.pi_kompatibilis": "Runs on Pi",
|
||||||
|
"common.rendszer_gyoker": "System (/)",
|
||||||
|
"common.torles": "Delete",
|
||||||
|
"common.ugyfel_azonosito": "Customer ID",
|
||||||
|
"common.ujrainditas": "Restart",
|
||||||
"layout.html_lang": "en",
|
"layout.html_lang": "en",
|
||||||
"launcher.inditopult": "Launcher",
|
"launcher.inditopult": "Launcher",
|
||||||
"launcher.inditopult_megosztasa": "Share the launcher",
|
"launcher.inditopult_megosztasa": "Share the launcher",
|
||||||
@@ -10,7 +26,6 @@
|
|||||||
"launcher.megosztas": "Share…",
|
"launcher.megosztas": "Share…",
|
||||||
"launcher.qr_kod_a_megosztasi_linkhez": "QR code for the share link",
|
"launcher.qr_kod_a_megosztasi_linkhez": "QR code for the share link",
|
||||||
"launcher.olvassa_be_telefonnal_a_gyors": "Scan it with your phone to open it quickly.",
|
"launcher.olvassa_be_telefonnal_a_gyors": "Scan it with your phone to open it quickly.",
|
||||||
"launcher.jelszo": "Password",
|
|
||||||
"launcher.a_megosztas_jelszoval_vedett": "The share is protected by a password.",
|
"launcher.a_megosztas_jelszoval_vedett": "The share is protected by a password.",
|
||||||
"launcher.jelszo_torlese": "Remove password",
|
"launcher.jelszo_torlese": "Remove password",
|
||||||
"launcher.jelszo_nem_kotelezo": "Password (optional)",
|
"launcher.jelszo_nem_kotelezo": "Password (optional)",
|
||||||
@@ -21,7 +36,6 @@
|
|||||||
"launcher.biztosan_kikapcsolja_a_megosztast_a": "Turn off sharing? The link stops working immediately.",
|
"launcher.biztosan_kikapcsolja_a_megosztast_a": "Turn off sharing? The link stops working immediately.",
|
||||||
"launcher.megosztas_kikapcsolasa": "Turn off sharing",
|
"launcher.megosztas_kikapcsolasa": "Turn off sharing",
|
||||||
"launcher.a_megosztas_jelenleg_ki_van": "Sharing is off.",
|
"launcher.a_megosztas_jelenleg_ki_van": "Sharing is off.",
|
||||||
"launcher.bezaras": "Close",
|
|
||||||
"launcher.megosztas_bekapcsolasa": "Turn on sharing",
|
"launcher.megosztas_bekapcsolasa": "Turn on sharing",
|
||||||
"launcher.masolva": "Copied",
|
"launcher.masolva": "Copied",
|
||||||
"launcher.inditopult_2": "Launcher — {{.Domain}}",
|
"launcher.inditopult_2": "Launcher — {{.Domain}}",
|
||||||
@@ -30,8 +44,6 @@
|
|||||||
"backups.kijelolod_ezt_a_meghajtot_a": "Use this drive for the system backup?",
|
"backups.kijelolod_ezt_a_meghajtot_a": "Use this drive for the system backup?",
|
||||||
"backups.kijelolom": "Use this drive",
|
"backups.kijelolom": "Use this drive",
|
||||||
"backups.tarhely_attekintes": "Storage overview",
|
"backups.tarhely_attekintes": "Storage overview",
|
||||||
"backups.rendszer": "System (/)",
|
|
||||||
"backups.levalasztva": "Disconnected",
|
|
||||||
"backups.db_mentesek": "Database backups",
|
"backups.db_mentesek": "Database backups",
|
||||||
"backups.fajl": "{{$n := len .Backup.DumpFiles}}{{$n}} {{if eq $n 1}}file{{else}}files{{end}}",
|
"backups.fajl": "{{$n := len .Backup.DumpFiles}}{{$n}} {{if eq $n 1}}file{{else}}files{{end}}",
|
||||||
"backups.rendszermentes_teljes_mentes": "System backup (full backup)",
|
"backups.rendszermentes_teljes_mentes": "System backup (full backup)",
|
||||||
@@ -68,9 +80,7 @@
|
|||||||
"backups.beagyazott_db_k_a_kotetmentesben": "embedded databases, inside the volume backup",
|
"backups.beagyazott_db_k_a_kotetmentesben": "embedded databases, inside the volume backup",
|
||||||
"backups.elinditod_a_teljes_rendszermentest_most": "Start the full system backup now? Your apps stop during the backup — usually for a few minutes, longer with more data.",
|
"backups.elinditod_a_teljes_rendszermentest_most": "Start the full system backup now? Your apps stop during the backup — usually for a few minutes, longer with more data.",
|
||||||
"backups.mentes_inditasa": "Starting the backup…",
|
"backups.mentes_inditasa": "Starting the backup…",
|
||||||
"backups.hiba": "Error",
|
|
||||||
"backups.mentes_folyamatban": "Backup in progress…",
|
"backups.mentes_folyamatban": "Backup in progress…",
|
||||||
"backups.hiba_2": "Error:",
|
|
||||||
"backups.allapot": "Status:",
|
"backups.allapot": "Status:",
|
||||||
"backups.a_rendszermentes_elkeszult": "The system backup is done.",
|
"backups.a_rendszermentes_elkeszult": "The system backup is done.",
|
||||||
"backups.a_mentes_sikertelen": "The backup failed.",
|
"backups.a_mentes_sikertelen": "The backup failed.",
|
||||||
@@ -79,20 +89,15 @@
|
|||||||
"backups.a_meghajto_kijelolve_a_beallitas": "The drive is assigned. The setting takes effect after the host agent next restarts.",
|
"backups.a_meghajto_kijelolve_a_beallitas": "The drive is assigned. The setting takes effect after the host agent next restarts.",
|
||||||
"backups.a_meghajto_kijelolve": "The drive is assigned.",
|
"backups.a_meghajto_kijelolve": "The drive is assigned.",
|
||||||
"app_info.alkalmazasok": "← Apps",
|
"app_info.alkalmazasok": "← Apps",
|
||||||
"app_info.elavult": "Outdated",
|
|
||||||
"app_info.megnyitas": "Open ↗",
|
"app_info.megnyitas": "Open ↗",
|
||||||
"app_info.naplo": "Log",
|
"app_info.naplo": "Log",
|
||||||
"app_info.torles": "Delete",
|
|
||||||
"app_info.exportalas": "Export",
|
"app_info.exportalas": "Export",
|
||||||
"app_info.beallitasok": "Settings",
|
"app_info.beallitasok": "Settings",
|
||||||
"app_info.telepites": "Install",
|
"app_info.telepites": "Install",
|
||||||
"app_info.mentesek": "Backups",
|
"app_info.mentesek": "Backups",
|
||||||
"app_info.hianyzo_tarhely": "Missing storage:",
|
"app_info.hianyzo_tarhely": "Missing storage:",
|
||||||
"app_info.ennek_az_alkalmazasnak_az_adattaroloja": "This app’s data storage is not available right now, so the app is stopped. Connect the drive again, or move the data to another storage.",
|
"app_info.ennek_az_alkalmazasnak_az_adattaroloja": "This app’s data storage is not available right now, so the app is stopped. Connect the drive again, or move the data to another storage.",
|
||||||
"app_info.hdd_szukseges": "Needs a hard drive",
|
|
||||||
"app_info.pi_kompatibilis": "Runs on Pi",
|
|
||||||
"app_info.csak_x86": "x86 only",
|
"app_info.csak_x86": "x86 only",
|
||||||
"app_info.magyar_felulet": "Hungarian interface",
|
|
||||||
"app_info.az_alkalmazas_fejlesztoje_felhagyott_a": "The developer of this app has stopped working on it. The installed version still works,\n but it gets no more updates or security fixes.",
|
"app_info.az_alkalmazas_fejlesztoje_felhagyott_a": "The developer of this app has stopped working on it. The installed version still works,\n but it gets no more updates or security fixes.",
|
||||||
"app_info.hova_tegyem_a_fajlokat": "Where do I put my files?",
|
"app_info.hova_tegyem_a_fajlokat": "Where do I put my files?",
|
||||||
"app_info.ezeket_a_mappakat_a_fajlkezeloben": "You reach these folders in the File manager. You may need to sign in to the File manager first.",
|
"app_info.ezeket_a_mappakat_a_fajlkezeloben": "You reach these folders in the File manager. You may need to sign in to the File manager first.",
|
||||||
@@ -113,14 +118,12 @@
|
|||||||
"app_info.athelyezed_a_z": "Move the",
|
"app_info.athelyezed_a_z": "Move the",
|
||||||
"app_info.adatait_ide": "data to:",
|
"app_info.adatait_ide": "data to:",
|
||||||
"app_info.az_alkalmazas_rovid_idore_leall": "? The app stops briefly. The old data is deleted only after a successful move.",
|
"app_info.az_alkalmazas_rovid_idore_leall": "? The app stops briefly. The old data is deleted only after a successful move.",
|
||||||
"app_info.hiba": "Error:",
|
|
||||||
"app_info.ismeretlen": "unknown",
|
"app_info.ismeretlen": "unknown",
|
||||||
"app_info.mire_hasznalhato": "What is it for?",
|
"app_info.mire_hasznalhato": "What is it for?",
|
||||||
"app_info.elso_lepesek": "First steps",
|
"app_info.elso_lepesek": "First steps",
|
||||||
"app_info.elofeltetelek": "Before you start",
|
"app_info.elofeltetelek": "Before you start",
|
||||||
"app_info.kezdeti_belepesi_adatok": "First sign-in details",
|
"app_info.kezdeti_belepesi_adatok": "First sign-in details",
|
||||||
"app_info.felhasznalonev": "Username",
|
"app_info.felhasznalonev": "Username",
|
||||||
"app_info.jelszo": "Password",
|
|
||||||
"app_info.az_uzemelteto_allitotta_be": "set by the operator",
|
"app_info.az_uzemelteto_allitotta_be": "set by the operator",
|
||||||
"app_info.megjelenites": "Show",
|
"app_info.megjelenites": "Show",
|
||||||
"app_info.masolas": "Copy",
|
"app_info.masolas": "Copy",
|
||||||
@@ -169,7 +172,6 @@
|
|||||||
"layout.ez_az_alkalmazas_mar_telepitve": "This app is already installed.",
|
"layout.ez_az_alkalmazas_mar_telepitve": "This app is already installed.",
|
||||||
"layout.frissites": "↻ Refreshing...",
|
"layout.frissites": "↻ Refreshing...",
|
||||||
"layout.sablonok_frissitve": "Templates refreshed",
|
"layout.sablonok_frissitve": "Templates refreshed",
|
||||||
"layout.hiba": "Error:",
|
|
||||||
"layout.ismeretlen_hiba": "Unknown error",
|
"layout.ismeretlen_hiba": "Unknown error",
|
||||||
"layout.halozati_hiba": "Network error:",
|
"layout.halozati_hiba": "Network error:",
|
||||||
"layout.folyamatban": "In progress...",
|
"layout.folyamatban": "In progress...",
|
||||||
@@ -180,11 +182,7 @@
|
|||||||
"layout.alkalmazas_torlese": "Delete app:",
|
"layout.alkalmazas_torlese": "Delete app:",
|
||||||
"layout.ez_a_muvelet_eltavolitja_a": "This removes the containers, the volumes and the configuration files.",
|
"layout.ez_a_muvelet_eltavolitja_a": "This removes the containers, the volumes and the configuration files.",
|
||||||
"layout.ez_a_muvelet_nem_visszavonhato": "You cannot undo this!",
|
"layout.ez_a_muvelet_nem_visszavonhato": "You cannot undo this!",
|
||||||
"layout.megsem": "Cancel",
|
|
||||||
"layout.torles": "Delete",
|
|
||||||
"layout.hiba_2": "Error",
|
|
||||||
"layout.nem_sikerult_lekerni_az_adatokat": "Could not load the details:",
|
"layout.nem_sikerult_lekerni_az_adatokat": "Could not load the details:",
|
||||||
"layout.bezaras": "Close",
|
|
||||||
"layout.torles_folyamatban": "Deleting...",
|
"layout.torles_folyamatban": "Deleting...",
|
||||||
"layout.torolt_adatok": "Deleted data:",
|
"layout.torolt_adatok": "Deleted data:",
|
||||||
"layout.megorzott_adatok": "Kept data:",
|
"layout.megorzott_adatok": "Kept data:",
|
||||||
@@ -202,7 +200,6 @@
|
|||||||
"layout.az_ejszakai_restic_pillanatkepek_nem": "The nightly restic snapshots cannot be deleted one by one — they expire automatically under the retention rules.",
|
"layout.az_ejszakai_restic_pillanatkepek_nem": "The nightly restic snapshots cannot be deleted one by one — they expire automatically under the retention rules.",
|
||||||
"layout.alkalmazas_eltavolitasa": "Remove app:",
|
"layout.alkalmazas_eltavolitasa": "Remove app:",
|
||||||
"layout.az_alkalmazas_visszaall_nincs_telepitve": "The app goes back to \"Not installed\". The template stays, and you can install it again.",
|
"layout.az_alkalmazas_visszaall_nincs_telepitve": "The app goes back to \"Not installed\". The template stays, and you can install it again.",
|
||||||
"layout.eltavolitas": "Remove",
|
|
||||||
"layout.eltavolitas_folyamatban": "Removing...",
|
"layout.eltavolitas_folyamatban": "Removing...",
|
||||||
"layout.torolt_mentesek": "Deleted backups:",
|
"layout.torolt_mentesek": "Deleted backups:",
|
||||||
"layout.nem_torolt_mentesek": "Backups not deleted:",
|
"layout.nem_torolt_mentesek": "Backups not deleted:",
|
||||||
@@ -236,5 +233,473 @@
|
|||||||
"func.restore_status.restoring": "Restoring...",
|
"func.restore_status.restoring": "Restoring...",
|
||||||
"func.restore_status.done": "Done",
|
"func.restore_status.done": "Done",
|
||||||
"func.restore_status.failed": "Failed",
|
"func.restore_status.failed": "Failed",
|
||||||
"func.restore_status.skipped": "Skipped"
|
"func.restore_status.skipped": "Skipped",
|
||||||
|
"dashboard.vezerlopult": "Dashboard",
|
||||||
|
"dashboard.futo_alkalmazas": "Running apps",
|
||||||
|
"dashboard.leallitva": "Stopped",
|
||||||
|
"dashboard.osszes_alkalmazas": "All apps",
|
||||||
|
"dashboard.memoria": "Memory",
|
||||||
|
"dashboard.homerseklet": "Temperature",
|
||||||
|
"dashboard.nem_ismert": "unknown",
|
||||||
|
"dashboard.a_tarhely_merete_most_nem": "The storage size cannot be read right now.",
|
||||||
|
"dashboard.fogyoban_a_hely": "Running out of space",
|
||||||
|
"dashboard.kritikusan_keves_hely": "Critically low on space",
|
||||||
|
"dashboard.lemezek_allapota": "Disk health",
|
||||||
|
"dashboard.nincs_adat": "No data",
|
||||||
|
"dashboard.biztonsagi_mentes": "Backup",
|
||||||
|
"dashboard.utolso_mentes": "Last backup:",
|
||||||
|
"dashboard.sikertelen": "Failed",
|
||||||
|
"dashboard.meg_nem_futott": "Not run yet",
|
||||||
|
"dashboard.adatbazisok": "Databases:",
|
||||||
|
"dashboard.mentve": "{{len .DBDumpStatus.Results}} backed up",
|
||||||
|
"dashboard.telepitett_alkalmazasok": "Installed apps",
|
||||||
|
"dashboard.az_alkalmazas_adattaroloja_nem_elerheto": "The app’s data storage is not available. Connect the drive again, or move the data to another storage.",
|
||||||
|
"dashboard.hianyzo_tarhely": "Missing storage: {{$ms}}",
|
||||||
|
"dashboard.az_alkalmazas_egyik_folyamatat_a": "The system stopped one of the app’s processes because it ran out of memory. A task may not have finished. Restart the app; if it happens again, tell the operator.",
|
||||||
|
"dashboard.memoria_elfogyott": "Out of memory",
|
||||||
|
"dashboard.az_alkalmazas_kornyezeteben_a_halozati": "In the app’s environment there is an empty local folder where the network storage should be — the data is not going to the NAS. Tell the operator.",
|
||||||
|
"dashboard.halozati_tarhely_hibas_az_alkalmazas": "Network storage broken — the app does not see the NAS",
|
||||||
|
"dashboard.a_halozati_tarhely_nas_jelenleg": "The network storage (NAS) is not reachable right now. The app is running; access to the data comes back when the NAS returns.",
|
||||||
|
"dashboard.halozati_tarhely_nem_elerheto": "Network storage not reachable: {{$nw}}",
|
||||||
|
"dashboard.a_proxy_traefik_csak_egeszseges": "The proxy (Traefik) publishes a public route only for a healthy container. While the app is not healthy, the URL returns 404, even though the container is running.",
|
||||||
|
"dashboard.url_nem_elerheto": "URL not reachable",
|
||||||
|
"dashboard.vedett": "Protected",
|
||||||
|
"dashboard.megnyitas": "Open",
|
||||||
|
"dashboard.telepites": "Install",
|
||||||
|
"dashboard.leallitas": "Stop",
|
||||||
|
"dashboard.inditas": "Start",
|
||||||
|
"dashboard.naplo": "Log",
|
||||||
|
"dashboard.nincs_elerheto_alkalmazas": "No app available.",
|
||||||
|
"stacks.alkalmazasok": "Apps",
|
||||||
|
"stacks.alkalmazas_visszaallitasa_exportalt_csom": "Restore an app from an exported package",
|
||||||
|
"stacks.importalas": "Import",
|
||||||
|
"stacks.sablonok_frissitese_a_kozponti_katalogus": "Refresh the templates from the central catalog",
|
||||||
|
"stacks.sablonok_frissitese": "↻ Refresh templates",
|
||||||
|
"stacks.futo": "Running",
|
||||||
|
"stacks.leallitva": "Stopped",
|
||||||
|
"stacks.telepitheto": "Installable",
|
||||||
|
"stacks.a_proxy_traefik_csak_egeszseges": "The proxy (Traefik) publishes a public route only for a healthy container. While the app is not healthy, the URL is not reachable (404), even though the container is running.",
|
||||||
|
"stacks.url_nem_elerheto_utvonal_nincs": "URL not reachable – route not published",
|
||||||
|
"stacks.az_alkalmazas_adattaroloja_nem_elerheto": "The app’s data storage is not available. Connect the drive again, or move the data.",
|
||||||
|
"stacks.hianyzo_tarhely": "Missing storage: {{$ms}}",
|
||||||
|
"stacks.az_alkalmazas_kornyezeteben_a_halozati": "In the app’s environment there is an empty local folder where the network storage should be — the data is not going to the NAS. Tell the operator.",
|
||||||
|
"stacks.halozati_tarhely_hibas_az_alkalmazas": "Network storage broken — the app does not see the NAS",
|
||||||
|
"stacks.a_halozati_tarhely_nas_jelenleg": "The network storage (NAS) is not reachable right now. The app is running; access to the data comes back when the NAS returns.",
|
||||||
|
"stacks.halozati_tarhely_nem_elerheto": "Network storage not reachable: {{$nw}}",
|
||||||
|
"stacks.adattarolo": "Data storage: {{index $.StorageLabels .Name}}",
|
||||||
|
"stacks.vedett_rendszerkomponens": "Protected system component",
|
||||||
|
"stacks.reszletek": "Details",
|
||||||
|
"stacks.telepites": "Install",
|
||||||
|
"stacks.mentesek": "Backups",
|
||||||
|
"stacks.frissites": "Update",
|
||||||
|
"stacks.leallitas": "Stop",
|
||||||
|
"stacks.inditas": "Start",
|
||||||
|
"stacks.naplok": "Logs",
|
||||||
|
"logs.vissza": "← Back",
|
||||||
|
"logs.naplok": "{{.Stack.Meta.DisplayName}} — Logs",
|
||||||
|
"logs.elo": "Live",
|
||||||
|
"logs.szuneteltetes": "Pause",
|
||||||
|
"logs.frissites": "Refresh",
|
||||||
|
"logs.szunetelve": "Paused",
|
||||||
|
"logs.folytatas": "Resume",
|
||||||
|
"monitoring.rendszermonitor": "System monitor",
|
||||||
|
"monitoring.szerver_allapota_gazdagep": "Server health (host)",
|
||||||
|
"monitoring.a_gazdagep_metrikai_jelenleg_nem": "The host metrics are not available right now.",
|
||||||
|
"monitoring.cpu_hasznalat": "CPU usage",
|
||||||
|
"monitoring.terheles_load": "Load",
|
||||||
|
"monitoring.memoria": "Memory",
|
||||||
|
"monitoring.cpu_homerseklet": "CPU temperature",
|
||||||
|
"monitoring.uzemido": "Uptime",
|
||||||
|
"monitoring.tarolok_kapacitasa": "Storage capacity",
|
||||||
|
"monitoring.rendszer_attekintes": "System overview",
|
||||||
|
"monitoring.gepnev": "Hostname",
|
||||||
|
"monitoring.operacios_rendszer": "Operating system",
|
||||||
|
"monitoring.inditas": "Boot time",
|
||||||
|
"monitoring.tarhely": "Storage",
|
||||||
|
"monitoring.hub_kapcsolat": "Hub connection",
|
||||||
|
"monitoring.kapcsolodva_a_kozponti_rendszer_aktivan": "Connected — the central system is actively watching the server.",
|
||||||
|
"monitoring.nem_elerheto_a_kozponti_rendszer": "Not reachable — the central system has not received a recent report.",
|
||||||
|
"monitoring.utolso_sikeres_jelentes": "Last successful report",
|
||||||
|
"monitoring.utolso_hiba": "Last error",
|
||||||
|
"monitoring.a_hub_kapcsolat_nincs_bekapcsolva": "The hub connection is not turned on — central monitoring is not active.",
|
||||||
|
"monitoring.rendszer_metrikak": "System metrics",
|
||||||
|
"monitoring.1_ora": "1 hour",
|
||||||
|
"monitoring.6_ora": "6 hours",
|
||||||
|
"monitoring.24_ora": "24 hours",
|
||||||
|
"monitoring.7_nap": "7 days",
|
||||||
|
"monitoring.30_nap": "30 days",
|
||||||
|
"monitoring.cpu_hasznalat_2": "CPU usage (%)",
|
||||||
|
"monitoring.memoria_hasznalat_gb": "Memory usage (GB)",
|
||||||
|
"monitoring.homerseklet_c": "Temperature (°C)",
|
||||||
|
"monitoring.terheles_load_average": "Load average",
|
||||||
|
"monitoring.meg_nincsenek_adatok_a_metrikak": "No data yet. Metric collection has started; the first data appears in a few minutes.",
|
||||||
|
"monitoring.memoria_eloszlas": "Memory breakdown",
|
||||||
|
"monitoring.alkalmazas_eroforrasok": "App resources",
|
||||||
|
"monitoring.memoria_hasznalat_mb": "Memory usage (MB)",
|
||||||
|
"monitoring.meg_nincsenek_kontener_adatok": "No container data yet.",
|
||||||
|
"monitoring.memoria_mb": "Memory (MB)",
|
||||||
|
"monitoring.hasznalt": "Used:",
|
||||||
|
"monitoring.rendszer_title": "System:",
|
||||||
|
"monitoring.rendszer_2": "System (",
|
||||||
|
"monitoring.szabad": "Free (",
|
||||||
|
"monitoring.eroforras_elozmenyek": "— Resource history",
|
||||||
|
"monitoring.nincs_tarolo_adat": "No storage data.",
|
||||||
|
"monitoring.nem_elerheto": "Not reachable",
|
||||||
|
"monitoring.kopas": "wear:",
|
||||||
|
"monitoring.frissitve": "Updated:",
|
||||||
|
"monitoring.nap": "d,",
|
||||||
|
"monitoring.ora": "h",
|
||||||
|
"monitoring.ora_2": "h,",
|
||||||
|
"monitoring.perc": "min",
|
||||||
|
"app_import.alkalmazasok": "← Apps",
|
||||||
|
"app_import.alkalmazas_importalas": "Import an app",
|
||||||
|
"app_import.fab_csomag_feltoltese_huzza_ide": "Upload a .fab package — drag it here, or choose the file",
|
||||||
|
"app_import.fajl_kivalasztasa": "Choose file",
|
||||||
|
"app_import.feltoltes_0": "Upload: 0%",
|
||||||
|
"app_import.megszakitas": "Cancel upload",
|
||||||
|
"app_import.nem_talalhato_fab_csomag_a": "No .fab package found on the registered storages.",
|
||||||
|
"app_import.exportalj_egy_alkalmazast_az_alkalmazas": "Export an app from its page, upload a .fab file above, or copy one into the <code>{storage}/felhom-data/exports/</code> folder.",
|
||||||
|
"app_import.alkalmazas": "App",
|
||||||
|
"app_import.datum": "Date",
|
||||||
|
"app_import.meret": "Size",
|
||||||
|
"app_import.tarolo": "Storage",
|
||||||
|
"app_import.reszletek": "Details »",
|
||||||
|
"app_import.csomag_reszletei": "Package details",
|
||||||
|
"app_import.ez_a_csomag_jelszoval_vedett": "This package is protected by a password. Enter the password:",
|
||||||
|
"app_import.megnyitas": "Open",
|
||||||
|
"app_import.alkalmazas_2": "App:",
|
||||||
|
"app_import.exportalva": "Exported:",
|
||||||
|
"app_import.controller_verzio": "Controller version:",
|
||||||
|
"app_import.adatbazis": "Database:",
|
||||||
|
"app_import.adatok": "Data:",
|
||||||
|
"app_import.meret_2": "Size:",
|
||||||
|
"app_import.figyelem_a_meglevo": "<strong>⚠ WARNING:</strong> The existing",
|
||||||
|
"app_import.alkalmazas_konfiguracioja_es_osszes_adat": "app’s configuration and all its data will be overwritten!",
|
||||||
|
"app_import.visszaallitas_inditasa": "Start restore",
|
||||||
|
"app_import.importalas_folyamata": "Import progress",
|
||||||
|
"app_import.importalas_kesz": "Import done!",
|
||||||
|
"app_import.az_alkalmazas_sikeresen_visszaallitva": "The app was restored.",
|
||||||
|
"app_import.alkalmazasok_megtekintese": "View apps",
|
||||||
|
"app_import.hibas_jelszo": "Wrong password",
|
||||||
|
"app_import.csomag_reszletei_2": "— Package details",
|
||||||
|
"app_import.nincs": "None",
|
||||||
|
"app_import.alkalmazas_megtekintese": "View app",
|
||||||
|
"app_import.a_feltoltes_megszakadt_ellenorizze_a": "The upload stopped — check the connection, then try again.",
|
||||||
|
"app_import.feltoltes": "Upload:",
|
||||||
|
"app_import.csak_fab_fajl_toltheto_fel": "Only a .fab file can be uploaded.",
|
||||||
|
"app_import.feltoltes_kesz": "Upload done:",
|
||||||
|
"app_export.alkalmazasok": "← Apps",
|
||||||
|
"app_export.exportalas": "{{.Stack.Meta.DisplayName}} — Export",
|
||||||
|
"app_export.mentes_helye": "Save to",
|
||||||
|
"app_export.valassz_tarolot": "Choose a storage...",
|
||||||
|
"app_export.konfiguracio": "Configuration:",
|
||||||
|
"app_export.felhasznaloi_adatok": "Your data:",
|
||||||
|
"app_export.osszesen": "Total:",
|
||||||
|
"app_export.szabad": "(free: -)",
|
||||||
|
"app_export.becsult_ido": "Estimated time:",
|
||||||
|
"app_export.mindig_resze_a_mentesnek": "Always part of the export:",
|
||||||
|
"app_export.valaszthato_tartalom": "Optional content:",
|
||||||
|
"app_export.a_kihagyott_mappak_tartalma_a": "The content of the skipped folders is always reachable in the File manager, and you can save it separately.",
|
||||||
|
"app_export.kihagyott_tartalom_megjelenitese": "Show skipped content",
|
||||||
|
"app_export.jelszo_opcionalis": "Password (optional)",
|
||||||
|
"app_export.titkositasi_jelszo": "Encryption password",
|
||||||
|
"app_export.jelszo_mutatasa": "Show password",
|
||||||
|
"app_export.alkalmazas_leallitasa_mentes_elott_ajanl": "Stop the app before the export (recommended)",
|
||||||
|
"app_export.az_adatok_konzisztenciaja_erdekeben_java": "To keep the data consistent, stop the app during the export.",
|
||||||
|
"app_export.exportalas_inditasa": "Start export",
|
||||||
|
"app_export.kesz": "Done!",
|
||||||
|
"app_export.megnyitas_filebrowser_ben": "Open in FileBrowser ↗",
|
||||||
|
"app_export.szabad_2": "(free:",
|
||||||
|
"app_export.perc": "min",
|
||||||
|
"app_export.nincs_eleg_szabad_hely_a": "Not enough free space on the chosen storage!",
|
||||||
|
"app_export.alap_mentes": "Base export: ~",
|
||||||
|
"app_export.a_kihagyott_nagy_meretu_tartalommal": ". With the large skipped content: ~",
|
||||||
|
"app_export.kihagyott_tartalom_elrejtese": "Hide skipped content",
|
||||||
|
"deploy.vissza": "← Back",
|
||||||
|
"deploy.beallitasok": "Settings",
|
||||||
|
"deploy.telepites": "Install",
|
||||||
|
"deploy.leallitas": "Stop",
|
||||||
|
"deploy.inditas": "Start",
|
||||||
|
"deploy.megnyitas": "Open ↗",
|
||||||
|
"deploy.reszletek": "Details",
|
||||||
|
"deploy.reszletes_leiras_kepernyokepek": "Full description, screenshots",
|
||||||
|
"deploy.ez_az_alkalmazas_mar_telepitve": "This app is already installed. The settings below are read-only.",
|
||||||
|
"deploy.adattarolas": "Data storage",
|
||||||
|
"deploy.tarhely": "Storage",
|
||||||
|
"deploy.adatmeret": "Data size",
|
||||||
|
"deploy.szabad_hely": "Free space",
|
||||||
|
"deploy.szabad": "{{.StorageInfo.FreeHuman}} ({{printf \"%.0f\" .StorageInfo.FreePercent}}% free)",
|
||||||
|
"deploy.mozgatas_masik_tarolora": "Move to another storage",
|
||||||
|
"deploy.korabbi_adatok": "Earlier data",
|
||||||
|
"deploy.az_alkalmazas_adatainak_masolata_megtala": "A copy of this app’s data is also on another storage.\n This is usually left behind after a move.",
|
||||||
|
"deploy.meret": "Size",
|
||||||
|
"deploy.mappak": "Folders",
|
||||||
|
"deploy.korabbi_adatok_torlese": "Delete earlier data",
|
||||||
|
"deploy.biztonsagi_mentes": "Backup",
|
||||||
|
"deploy.az_alkalmazas_adatbazisa_es_docker": "The app’s database and Docker volumes go into the nightly backup automatically.\n <a href=\"/backups\" style=\"color:var(--blue)\">Backup status →</a> · <a href=\"/stacks/{{.Stack.Name}}/backup\" style=\"color:var(--blue)\">Backup settings →</a>",
|
||||||
|
"deploy.integraciok": "Integrations",
|
||||||
|
"deploy.mas_telepitett_alkalmazasokkal_valo_ossz": "Connections to other installed apps. An integration pauses by itself when either app stops, and turns on again when it starts.",
|
||||||
|
"deploy.nincs_telepitve": "Not installed",
|
||||||
|
"deploy.celalkalmazas_leallitva": "Target app stopped",
|
||||||
|
"deploy.aktiv": "Active",
|
||||||
|
"deploy.a_celalkalmazas_nincs_telepitve": "The target app is not installed",
|
||||||
|
"deploy.a_celalkalmazas_nem_fut": "The target app is not running",
|
||||||
|
"deploy.halozati_hiba": "Network error",
|
||||||
|
"deploy.foldrajzi_korlatozas": "Country restriction",
|
||||||
|
"deploy.az_alkalmazas_egyeni_orszagkorlatozas_ne": "Without its own country restriction, the app follows the global setting.",
|
||||||
|
"deploy.egyeni_orszagkorlatozas": "Own country restriction",
|
||||||
|
"deploy.engedelyezett_orszagok_ehhez_az_alkalmaz": "Allowed countries for this app",
|
||||||
|
"deploy.orszag_keresese": "Search country...",
|
||||||
|
"deploy.mentes": "Save",
|
||||||
|
"deploy.nincs_talalat": "No match",
|
||||||
|
"deploy.mentve": "Saved",
|
||||||
|
"deploy.opcionalis_beallitasok": "Optional settings",
|
||||||
|
"deploy.regisztracios_utmutato": "Sign-up guide ↗",
|
||||||
|
"deploy.mentes_2": "Saving...",
|
||||||
|
"deploy.email_kuldes": "Sending e-mail",
|
||||||
|
"deploy.ez_az_alkalmazas_tud_emailt": "This app can send e-mail (for example password resets, invitations) through Felhom,\n without setting up a separate provider. The sender address: <strong>{{.AppEmailFromAddress}}</strong>.",
|
||||||
|
"deploy.az_alkalmazas_email_jelenleg_ki": "App e-mail is turned off globally right now. Turn it on on the\n <a href=\"/settings\">Settings</a> page for it to work here too.",
|
||||||
|
"deploy.email_kuldes_engedelyezese_ennel_az": "Allow sending e-mail for this app",
|
||||||
|
"deploy.a_mentes_ujrainditja_az_alkalmazast": "Saving restarts the app.",
|
||||||
|
"deploy.nincs_eleg_memoria_foglalas_telepites": "Not enough memory! Reserved after install: {{.AfterMB}} MB / {{.UsableMB}} MB",
|
||||||
|
"deploy.memoria": "Memory",
|
||||||
|
"deploy.jelenlegi_hasznalat_mb": "Current usage: {{.UsedMB}} MB",
|
||||||
|
"deploy.jelenlegi_hasznalat_mb_2": "Current usage ({{.UsedMB}} MB)",
|
||||||
|
"deploy.az_alkalmazasok_csucsterhelese_meghaladh": "The apps’ peak load can go above the available memory.\n In normal use this causes no problem.",
|
||||||
|
"deploy.ennek_az_alkalmazasnak_van_korabbi": "This app has an earlier backup, so we filled in the fields below from its own backup.",
|
||||||
|
"deploy.korabbi_webcim": "Earlier web address: <strong>{{.RestoreRecordedAddress}}</strong>.",
|
||||||
|
"deploy.ha_most_mashova_szeretned_telepiteni": "If you want to install it somewhere else now, change it — we will point out the difference before the restore.",
|
||||||
|
"deploy.az_alkalmazas_adatai_az_alabb": "The app’s data goes to the data drive chosen below.",
|
||||||
|
"deploy.hol_lesznek_az_adatok_ennel": "<strong>Where the data goes:</strong> this app has no separate data drive choice,\n so its data goes to the system drive (<code>{{.SystemDataPath}}</code>). Its backups are made all the same.",
|
||||||
|
"deploy.nincs_eleg_szabad_tarhely_a": "Not enough free storage for the install. {{.DockerFreeHuman}} is free now, and the system keeps\n {{.DockerReserveHuman}} in reserve to protect the core services (controller, proxy).\n So the install is blocked for now — free up space, or add storage.",
|
||||||
|
"deploy.automatikusan_generalt_ertekek": "Automatically generated values",
|
||||||
|
"deploy.ezek_az_ertekek_automatikusan_jottek": "These values were created automatically at install.",
|
||||||
|
"deploy.ezek_az_ertekek_a_telepitessel": "These values are saved together with the install. Write down the passwords you need!",
|
||||||
|
"deploy.automatikusan_generalva": "Generated automatically",
|
||||||
|
"deploy.megjelenites": "Show",
|
||||||
|
"deploy.telepites_utan_nem_modosithato": "cannot be changed after install",
|
||||||
|
"deploy.az_aldomain_telepites_utan_nem": "The subdomain cannot be changed after install. To change it, remove the app and install it again (all data is deleted).",
|
||||||
|
"deploy.generalas": "Generate",
|
||||||
|
"deploy.telepiteskor_beallitott_kezdeti_jelszo_h": "The first password set at install — if you changed it in the app, it is not updated here.",
|
||||||
|
"deploy.jelszo_megerositese": "Confirm password",
|
||||||
|
"deploy.igen": "Yes",
|
||||||
|
"deploy.szabad_2": "{{.Label}} — {{.FreeHuman}} free",
|
||||||
|
"deploy.alapertelmezett": "(default)",
|
||||||
|
"deploy.nem_elerheto": "{{$.CurrentHDDPath}} (not available)",
|
||||||
|
"deploy.a_kivalasztott_tarhely_majdnem_megtelt": "The chosen storage is almost full.",
|
||||||
|
"deploy.a_kivalasztott_meghajton_az_alkalmazas": "The chosen drive stores the app’s <strong>files</strong> (media, documents).\n The <strong>database runs on the fast internal SSD</strong> — and it is backed up together with the app.",
|
||||||
|
"deploy.nincs_regisztralt_adattarolo_adja_meg": "No registered data storage — enter the path by hand",
|
||||||
|
"deploy.nincs_eleg_szabad_tarhely": "Not enough free storage",
|
||||||
|
"deploy.nincs_eleg_memoria": "Not enough memory",
|
||||||
|
"deploy.telepites_inditasa": "Start install",
|
||||||
|
"deploy.telepites_folyamatban": "Installing...",
|
||||||
|
"deploy.konfiguracio_mentese": "Saving the configuration...",
|
||||||
|
"deploy.kontener_ek_inditasa": "Starting the container(s)...",
|
||||||
|
"deploy.alkalmazas_inicializalasa": "Initialising the app...",
|
||||||
|
"deploy.alkalmazas_megnyitasa": "Open the app ↗",
|
||||||
|
"deploy.elso_lepesek": "First steps",
|
||||||
|
"deploy.masolas": "Copy",
|
||||||
|
"deploy.bejelentkezes": "Sign-in",
|
||||||
|
"deploy.dokumentacio": "Documentation ↗",
|
||||||
|
"deploy.beallitasok_es_jelszavak_megtekintese": "View settings and passwords",
|
||||||
|
"deploy.alkalmazasok": "← Apps",
|
||||||
|
"deploy.a_lekeres_nem_sikerult": "The request failed.",
|
||||||
|
"deploy.elrejtes": "Hide",
|
||||||
|
"deploy.masolva": "Copied!",
|
||||||
|
"deploy.biztosan_torolni_szeretned_a_korabbi": "Delete the earlier data? Storage:",
|
||||||
|
"deploy.figyelem_a_muvelet_visszavonhatatlan_elo": "— WARNING: this cannot be undone! First make sure the app works properly from the new storage.",
|
||||||
|
"deploy.utolso_figyelmeztetes_a_torles_visszavon": "LAST WARNING! The deletion cannot be undone. Continue?",
|
||||||
|
"deploy.torles_folyamatban": "Deleting...",
|
||||||
|
"deploy.ismeretlen_hiba": "Unknown error",
|
||||||
|
"deploy.korabbi_adatok_torolve_n_nfelszabaditott": "Earlier data deleted!\\n\\nSpace freed:",
|
||||||
|
"deploy.n_nnehany_hiba_tortent_n": "\\n\\nSome errors occurred:\\n",
|
||||||
|
"deploy.halozati_hiba_2": "Network error:",
|
||||||
|
"deploy.kotelezo_mezo": "Required field:",
|
||||||
|
"deploy.nhasznalja_a_generalas_gombot_vagy": "\\nUse the Generate button or type a password.",
|
||||||
|
"deploy.a_ket_jelszo_nem_egyezik": "The two passwords do not match:",
|
||||||
|
"deploy.az_aldomain_csak_kisbetuket_szamokat": "The subdomain may contain only lowercase letters, digits and hyphens, and cannot start or end with a hyphen.",
|
||||||
|
"deploy.konfiguracio_mentve": "Configuration saved",
|
||||||
|
"deploy.masodperce": "seconds ago...",
|
||||||
|
"deploy.idotullepes_az_alkalmazas_meg_indulhat": "Timed out — the app may still be starting",
|
||||||
|
"deploy.a_telepites_idotullepesbe_futott_az": "The install timed out. The app may still be starting.",
|
||||||
|
"deploy.telepites_sikertelen": "Install failed",
|
||||||
|
"deploy.a_telepites_nem_sikerult": "The install failed:",
|
||||||
|
"deploy.naplok_megtekintese": "View logs",
|
||||||
|
"deploy.alkalmazasok_2": "Apps",
|
||||||
|
"deploy.kepek_letoltese_kontenerek_inditasa": "Downloading images, starting containers...",
|
||||||
|
"deploy.kontenerek_elindultak": "Containers started",
|
||||||
|
"deploy.alkalmazas_kesz": "App ready!",
|
||||||
|
"deploy.telepites_sikeres": "Install succeeded!",
|
||||||
|
"deploy.az_alkalmazas_sikeresen_telepitve_es": "The app is installed and running!",
|
||||||
|
"deploy.allapotjelzo_meg_inicializal": "Health check: still initialising",
|
||||||
|
"deploy.az_alkalmazas_elindult_de_meg": "The app started, but it is still initialising.",
|
||||||
|
"deploy.ez_normalis_az_elso_percekben": "This is normal in the first minutes — the app may already be reachable.",
|
||||||
|
"deploy.a_kontener_leallt": "The container stopped",
|
||||||
|
"deploy.a_kontener_leallt_ellenorizze_a": "The container stopped. Check the logs.",
|
||||||
|
"settings_system.beallitasok_rendszer": "Settings — System",
|
||||||
|
"settings_system.rendszer_konfiguracio": "System configuration",
|
||||||
|
"settings_system.az_uzemelteto_altal_beallitott_ertekek": "Values set by the operator. Ask the operator to change them.",
|
||||||
|
"settings_system.ugyfel_neve": "Customer name",
|
||||||
|
"settings_system.alkalmazas_sablon_forras": "App template source",
|
||||||
|
"settings_system.sablon_szinkronizalas": "Template sync",
|
||||||
|
"settings_system.biztonsagi_mentes": "Backup",
|
||||||
|
"settings_system.aktiv": "Active",
|
||||||
|
"settings_system.inaktiv": "Inactive",
|
||||||
|
"settings_system.mentes_utemezes": "Backup schedule",
|
||||||
|
"settings_system.hub_jelentes": "Hub reporting",
|
||||||
|
"settings_system.verzio_es_frissites": "Version and update",
|
||||||
|
"settings_system.jelenlegi_verzio": "Current version",
|
||||||
|
"settings_system.legujabb_verzio": "Latest version",
|
||||||
|
"settings_system.frissites_elerheto": "● Update available",
|
||||||
|
"settings_system.naprakesz": "— up to date",
|
||||||
|
"settings_system.utolso_ellenorzes": "Last check",
|
||||||
|
"settings_system.nyilvanos_hitelesites_nelkul": "public (no authentication)",
|
||||||
|
"settings_system.hitelesitett": "authenticated",
|
||||||
|
"settings_system.automatikus_frissites": "Automatic update",
|
||||||
|
"settings_system.minimalis_verzio_uzemelteto": "Minimum version (operator)",
|
||||||
|
"settings_system.a_rendszer_automatikusan_erre_a": "— the system updates to this version automatically if it is older",
|
||||||
|
"settings_system.allapot": "Status",
|
||||||
|
"settings_system.frissites_folyamatban_a_vezerlo_hamarosa": "Update in progress — the controller restarts soon…",
|
||||||
|
"settings_system.utolso_frissites": "Last update",
|
||||||
|
"settings_system.sikeres": "Succeeded",
|
||||||
|
"settings_system.sikertelen": "Failed",
|
||||||
|
"settings_system.folyamatban": "In progress",
|
||||||
|
"settings_system.frissites_keresese": "Check for updates",
|
||||||
|
"settings_system.frissites_telepitese": "Install update",
|
||||||
|
"settings_system.halozat": "Network",
|
||||||
|
"settings_system.helyi_cim_lan": "Local address (LAN)",
|
||||||
|
"settings_system.nem_allapithato_meg": "cannot be determined",
|
||||||
|
"settings_system.halozati_nev": "Network name",
|
||||||
|
"settings_system.atjaro": "Gateway",
|
||||||
|
"settings_system.ezek_az_ertekek_a_helyi": "These values depend on the local network and can change. For remote troubleshooting, we ask you to read out this page.",
|
||||||
|
"settings_system.szerver_memoria_ram": "Server memory (RAM)",
|
||||||
|
"settings_system.jelenlegi_memoria": "Current memory",
|
||||||
|
"settings_system.felhasznalt": "Used",
|
||||||
|
"settings_system.megengedett_tartomany": "Allowed range",
|
||||||
|
"settings_system.uj_meret_mb": "New size (MB)",
|
||||||
|
"settings_system.atmeretezes": "Resize",
|
||||||
|
"settings_system.a_kiszolgalo_ugynok_jelenleg_nem": "The host agent is not reachable right now — try again later.",
|
||||||
|
"settings_system.a_memoria_atmeretezesehez_a_kiszolgalo": "Resizing memory needs a system update on the host.",
|
||||||
|
"settings_system.megerosites": "Confirm",
|
||||||
|
"settings_system.ellenorzes": "Checking...",
|
||||||
|
"settings_system.kapcsolodasi_hiba": "Connection error",
|
||||||
|
"settings_system.vezerlo_frissitese": "Update controller",
|
||||||
|
"settings_system.frissites": "Update",
|
||||||
|
"settings_system.biztosan_frissiti_a_controllert_n": "Update the controller?\\n\\nThe dashboard is unreachable for a short time during the update.",
|
||||||
|
"settings_system.frissites_2": "Updating...",
|
||||||
|
"settings_system.frissites_folyamatban": "Update in progress...",
|
||||||
|
"settings_system.ujraindulas": "Restarting...",
|
||||||
|
"settings_system.ervenytelen_memoria_ertek": "Invalid memory value",
|
||||||
|
"settings_system.memoria_csokkentese": "Reduce memory",
|
||||||
|
"settings_system.csokkentes": "Reduce",
|
||||||
|
"settings_system.a_memoria_csokkentese_hatassal_lehet": "Reducing memory can affect the performance of running apps. Continue?",
|
||||||
|
"settings_system.atmeretezes_2": "Resizing...",
|
||||||
|
"settings_system.kesz": "Done.",
|
||||||
|
"settings_system.a_muvelet_nem_sikerult": "The operation failed",
|
||||||
|
"settings_system.vezerlo_ujrainditasa": "Restart controller",
|
||||||
|
"settings_system.ha_a_vezerlo_hibasan_mukodik": "If the controller misbehaves, you can safely restart it here — no need to restart the whole server.\n Your apps keep running; only the controller restarts (a few seconds).",
|
||||||
|
"settings_system.kiszolgalo_ujrainditasa": "Restart server",
|
||||||
|
"settings_system.az_egesz_kiszolgalo_szerver_ujrainditasa": "Restarts the whole server. Every app stops for a short time, and the dashboard is unreachable for about 30 seconds. Use it when the whole system needs a restart — otherwise “Restart controller” above is enough.",
|
||||||
|
"settings_system.biztosan_ujrainditja_a_vezerlot_a": "Restart the controller? It takes a few seconds, and the page is unreachable for a short time.",
|
||||||
|
"settings_system.ujrainditas_folyamatban_ujracsatlakozas": "Restarting… reconnecting…",
|
||||||
|
"settings_system.biztosan_ujrainditja_a_kiszolgalot_az": "Restart the server? The apps and the dashboard become unreachable for about 30 seconds.",
|
||||||
|
"settings_system.ujrainditas_folyamatban_a_vezerlopult_ne": "Restarting… the dashboard reloads in a few seconds.",
|
||||||
|
"settings_system.az_ujrainditas_a_vartnal_tovabb": "The restart is taking longer than expected. Reload the page by hand.",
|
||||||
|
"settings_security.beallitasok_biztonsag_es_hozzaferes": "Settings — Security and access",
|
||||||
|
"settings_security.jelszo_modositas": "Change password",
|
||||||
|
"settings_security.jelenlegi_jelszo": "Current password",
|
||||||
|
"settings_security.adja_meg_a_jelenlegi_jelszavat": "Enter your current password",
|
||||||
|
"settings_security.uj_jelszo": "New password",
|
||||||
|
"settings_security.legalabb_8_karakter": "At least 8 characters",
|
||||||
|
"settings_security.uj_jelszo_megerositese": "Confirm new password",
|
||||||
|
"settings_security.jelszo_megegyszer": "Password again",
|
||||||
|
"settings_security.jelszo_modositasa": "Change password",
|
||||||
|
"settings_security.a_jelszavas_vedelem_nincs_beallitva": "Password protection is not set up. Ask the operator to set it up.",
|
||||||
|
"settings_security.foldrajzi_korlatozas": "Country restriction",
|
||||||
|
"settings_security.orszag_alapjan_korlatozhato_a_webes": "Access to the web apps can be limited by country with the Cloudflare WAF.",
|
||||||
|
"settings_security.a_helyi_halozati_hozzaferes_mindig": "Access from the local network is always allowed (it does not pass through Cloudflare).",
|
||||||
|
"settings_security.a_cloudflare_api_token_nincs": "The Cloudflare API token is not configured. Ask the operator to set it up.<br>\n <small>The token needs the <strong>Zone WAF:Edit</strong> permission.</small>",
|
||||||
|
"settings_security.geo_korlatozas_aktiv": "Country restriction active",
|
||||||
|
"settings_security.engedelyezett_orszagok_globalis": "Allowed countries (global)",
|
||||||
|
"settings_security.orszag_keresese": "Search country...",
|
||||||
|
"settings_security.csak_a_kivalasztott_orszagokbol_erheto": "The system is reachable only from the chosen countries.",
|
||||||
|
"settings_security.alkalmazas_specifikus_felulirasok": "Per-app overrides",
|
||||||
|
"settings_security.alkalmazas_kivalasztasa": "— Choose an app —",
|
||||||
|
"settings_security.hozzaadas": "+ Add",
|
||||||
|
"settings_security.mentes_es_szinkronizalas": "Save and sync",
|
||||||
|
"settings_security.kezi_szinkronizalas": "Sync by hand",
|
||||||
|
"settings_security.utolso_szinkronizalas": "Last sync: {{.GeoLastSync}}",
|
||||||
|
"settings_security.megerosites": "Confirm",
|
||||||
|
"settings_security.nincs_talalat": "No match",
|
||||||
|
"settings_security.figyelem_magyarorszag_eltavolitasa_azt_j": "Warning: removing Hungary means the system is not reachable remotely from a Hungarian IP either. Continue?",
|
||||||
|
"settings_security.magyarorszag_eltavolitasa_nem_ajanlott_f": "Removing Hungary is not recommended. Continue?",
|
||||||
|
"settings_security.nincs_alkalmazas_specifikus_beallitas_mi": "No per-app setting. Every app follows the global setting.",
|
||||||
|
"settings_security.szerkesztes": "Edit",
|
||||||
|
"settings_security.engedelyezett_orszagok": "Allowed countries:",
|
||||||
|
"settings_security.kesz": "Done",
|
||||||
|
"settings_security.mentes": "Saving...",
|
||||||
|
"settings_security.mentve": "Saved",
|
||||||
|
"settings_security.halozati_hiba": "Network error",
|
||||||
|
"settings_security.szinkronizalas_elinditva": "Sync started...",
|
||||||
|
"settings_security.utolso": "Last:",
|
||||||
|
"settings_security.veszhelyzeti_informaciok": "Emergency information",
|
||||||
|
"settings_security.ezeket_az_adatokat_mentse_el": "Keep these details in a safe place. You need them to restore the system after a reinstall.",
|
||||||
|
"settings_security.visszaallitasi_jelszo": "Retrieval password",
|
||||||
|
"settings_security.megjelenit": "Show",
|
||||||
|
"settings_security.tamogatas": "Support",
|
||||||
|
"settings_security.felhom_eu_kapcsolat": "<a href=\"mailto:{{.SupportEmail}}\" style=\"color: var(--blue);\">{{.SupportEmail}}</a>\n | \n <a href=\"{{.SupportURL}}\" target=\"_blank\" style=\"color: var(--blue);\">felhom.eu/kapcsolat</a>",
|
||||||
|
"settings_security.a_visszaallitasi_jelszo_lekerese_nem": "The retrieval password could not be loaded.",
|
||||||
|
"settings_security.elrejt": "Hide",
|
||||||
|
"settings_notifications.beallitasok_ertesitesek": "Settings — Notifications",
|
||||||
|
"settings_notifications.ertesitesek": "Notifications",
|
||||||
|
"settings_notifications.e_mail_cim": "E-mail address",
|
||||||
|
"settings_notifications.hibak_es_figyelmeztetesek": "Errors and warnings:",
|
||||||
|
"settings_notifications.biztonsagi_mentes_sikertelen": "Backup failed",
|
||||||
|
"settings_notifications.adatbazis_mentes_sikertelen": "Database backup failed",
|
||||||
|
"settings_notifications.mentes_serules_eszlelve": "Backup damage detected",
|
||||||
|
"settings_notifications.masodlagos_mentes_sikertelen": "Secondary backup failed",
|
||||||
|
"settings_notifications.tavoli_mentes_tarhelykeret_figyelmeztete": "Remote backup — storage quota warning",
|
||||||
|
"settings_notifications.lemez_beteloben_90_felett": "Disk filling up (over 90%)",
|
||||||
|
"settings_notifications.lemez_megtelt_vagy_meghibasodott": "Disk full or failed",
|
||||||
|
"settings_notifications.meghajto_levalasztva": "Drive disconnected",
|
||||||
|
"settings_notifications.szerver_nem_elerheto": "Server not reachable",
|
||||||
|
"settings_notifications.rendszer_allapot_kritikus": "System health critical",
|
||||||
|
"settings_notifications.elvart_fajlmentes_elmaradt": "Expected file backup missed",
|
||||||
|
"settings_notifications.elvart_adatbazismentes_elmaradt": "Expected database backup missed",
|
||||||
|
"settings_notifications.alkalmazas_nem_fut": "App not running",
|
||||||
|
"settings_notifications.tajekoztato": "For information:",
|
||||||
|
"settings_notifications.meghajto_ujra_csatlakoztatva": "Drive connected again",
|
||||||
|
"settings_notifications.rendszer_allapot_helyreallt": "System health recovered",
|
||||||
|
"settings_notifications.ertesitesi_szunet": "Notification pause",
|
||||||
|
"settings_notifications.ora_azonos_problema_eseten_ennyi": "hours (for the same problem, no new message is sent for this long)",
|
||||||
|
"settings_notifications.mentes": "Save",
|
||||||
|
"settings_notifications.teszt_email_kuldese": "Send test e-mail",
|
||||||
|
"settings_notifications.az_ertesitesek_a_kozponti_rendszeren": "Notifications work through the central system, which is not turned on right now.",
|
||||||
|
"settings_notifications.alkalmazas_email": "App e-mail",
|
||||||
|
"settings_notifications.az_alkalmazasok_a_felhom_on": "Apps can send e-mail through Felhom (for example password resets, invitations),\n without setting up a separate e-mail provider. Each app’s sender address is its own\n <em><app>@felhom.eu</em> address.",
|
||||||
|
"settings_notifications.alkalmazas_email_engedelyezese": "Allow app e-mail",
|
||||||
|
"settings_notifications.felado_neve_opcionalis": "Sender name (optional)",
|
||||||
|
"settings_notifications.pl_a_haztartas_neve": "for example the household name",
|
||||||
|
"settings_notifications.ez_jelenik_meg_a_kimeno": "This appears as the sender of outgoing e-mails, next to the app name.",
|
||||||
|
"settings_notifications.bekapcsolas_utan_az_egyes_alkalmazasokna": "After turning it on, allow sending e-mail for each app too (on the app’s page).",
|
||||||
|
"stacks.mind": "All",
|
||||||
|
"app_export.folyamat": "Progress",
|
||||||
|
"app_import.titkos": "Encrypted",
|
||||||
|
"monitoring.processzor": "Processor",
|
||||||
|
"deploy.hamarosan": "Coming soon",
|
||||||
|
"deploy.az_adatai_itt_voltak": "Its data was here: <strong>{{.RestoreRecordedDrive}}</strong>.",
|
||||||
|
"deploy.aldomain_placeholder": "subdomain",
|
||||||
|
"settings_security.figyelem": "Warning",
|
||||||
|
"settings_notifications.pelda_email": "example@email.com",
|
||||||
|
"page.title.dashboard": "Dashboard",
|
||||||
|
"page.title.stacks": "Apps",
|
||||||
|
"page.title.monitoring": "System monitor",
|
||||||
|
"page.title.settings": "Settings",
|
||||||
|
"page.title.settings_notifications": "Notifications",
|
||||||
|
"page.title.settings_security": "Security and access",
|
||||||
|
"func.infra.cloudflared.description": "Secure internet connection — the server is reachable from outside without opening ports.",
|
||||||
|
"func.infra.traefik.description": "Traffic router (reverse proxy) — sends each request to the right app.",
|
||||||
|
"func.infra.filebrowser.description": "File manager — browse the storage files from your browser.",
|
||||||
|
"func.infra.samba.display": "Network sharing",
|
||||||
|
"func.infra.samba.description": "File sharing on the local network — the folders appear in Windows Explorer and the Mac Finder."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,20 @@
|
|||||||
{
|
{
|
||||||
|
"common.bezaras": "Bezárás",
|
||||||
|
"common.elavult": "Elavult",
|
||||||
|
"common.eltavolitas": "Eltávolítás",
|
||||||
|
"common.hdd_szukseges": "HDD szükséges",
|
||||||
|
"common.hiba": "Hiba",
|
||||||
|
"common.hiba_kettospont": "Hiba:",
|
||||||
|
"common.hiba_tortent": "Hiba történt",
|
||||||
|
"common.jelszo": "Jelszó",
|
||||||
|
"common.levalasztva": "Leválasztva",
|
||||||
|
"common.magyar_felulet": "Magyar felület",
|
||||||
|
"common.megsem": "Mégsem",
|
||||||
|
"common.pi_kompatibilis": "Pi kompatibilis",
|
||||||
|
"common.rendszer_gyoker": "Rendszer (/)",
|
||||||
|
"common.torles": "Törlés",
|
||||||
|
"common.ugyfel_azonosito": "Ügyfél azonosító",
|
||||||
|
"common.ujrainditas": "Újraindítás",
|
||||||
"layout.html_lang": "hu",
|
"layout.html_lang": "hu",
|
||||||
"launcher.inditopult": "Indítópult",
|
"launcher.inditopult": "Indítópult",
|
||||||
"launcher.inditopult_megosztasa": "Indítópult megosztása",
|
"launcher.inditopult_megosztasa": "Indítópult megosztása",
|
||||||
@@ -10,7 +26,6 @@
|
|||||||
"launcher.megosztas": "Megosztás…",
|
"launcher.megosztas": "Megosztás…",
|
||||||
"launcher.qr_kod_a_megosztasi_linkhez": "QR-kód a megosztási linkhez",
|
"launcher.qr_kod_a_megosztasi_linkhez": "QR-kód a megosztási linkhez",
|
||||||
"launcher.olvassa_be_telefonnal_a_gyors": "Olvassa be telefonnal a gyors megnyitáshoz.",
|
"launcher.olvassa_be_telefonnal_a_gyors": "Olvassa be telefonnal a gyors megnyitáshoz.",
|
||||||
"launcher.jelszo": "Jelszó",
|
|
||||||
"launcher.a_megosztas_jelszoval_vedett": "A megosztás jelszóval védett.",
|
"launcher.a_megosztas_jelszoval_vedett": "A megosztás jelszóval védett.",
|
||||||
"launcher.jelszo_torlese": "Jelszó törlése",
|
"launcher.jelszo_torlese": "Jelszó törlése",
|
||||||
"launcher.jelszo_nem_kotelezo": "Jelszó (nem kötelező)",
|
"launcher.jelszo_nem_kotelezo": "Jelszó (nem kötelező)",
|
||||||
@@ -21,7 +36,6 @@
|
|||||||
"launcher.biztosan_kikapcsolja_a_megosztast_a": "Biztosan kikapcsolja a megosztást? A link azonnal érvénytelenné válik.",
|
"launcher.biztosan_kikapcsolja_a_megosztast_a": "Biztosan kikapcsolja a megosztást? A link azonnal érvénytelenné válik.",
|
||||||
"launcher.megosztas_kikapcsolasa": "Megosztás kikapcsolása",
|
"launcher.megosztas_kikapcsolasa": "Megosztás kikapcsolása",
|
||||||
"launcher.a_megosztas_jelenleg_ki_van": "A megosztás jelenleg ki van kapcsolva.",
|
"launcher.a_megosztas_jelenleg_ki_van": "A megosztás jelenleg ki van kapcsolva.",
|
||||||
"launcher.bezaras": "Bezárás",
|
|
||||||
"launcher.megosztas_bekapcsolasa": "Megosztás bekapcsolása",
|
"launcher.megosztas_bekapcsolasa": "Megosztás bekapcsolása",
|
||||||
"launcher.masolva": "Másolva",
|
"launcher.masolva": "Másolva",
|
||||||
"launcher.inditopult_2": "Indítópult — {{.Domain}}",
|
"launcher.inditopult_2": "Indítópult — {{.Domain}}",
|
||||||
@@ -30,8 +44,6 @@
|
|||||||
"backups.kijelolod_ezt_a_meghajtot_a": "Kijelölöd ezt a meghajtót a rendszermentés helyéül?",
|
"backups.kijelolod_ezt_a_meghajtot_a": "Kijelölöd ezt a meghajtót a rendszermentés helyéül?",
|
||||||
"backups.kijelolom": "Kijelölöm",
|
"backups.kijelolom": "Kijelölöm",
|
||||||
"backups.tarhely_attekintes": "Tárhely áttekintés",
|
"backups.tarhely_attekintes": "Tárhely áttekintés",
|
||||||
"backups.rendszer": "Rendszer (/)",
|
|
||||||
"backups.levalasztva": "Leválasztva",
|
|
||||||
"backups.db_mentesek": "DB mentések",
|
"backups.db_mentesek": "DB mentések",
|
||||||
"backups.fajl": "{{len .Backup.DumpFiles}} fájl",
|
"backups.fajl": "{{len .Backup.DumpFiles}} fájl",
|
||||||
"backups.rendszermentes_teljes_mentes": "Rendszermentés (teljes mentés)",
|
"backups.rendszermentes_teljes_mentes": "Rendszermentés (teljes mentés)",
|
||||||
@@ -68,9 +80,7 @@
|
|||||||
"backups.beagyazott_db_k_a_kotetmentesben": "beágyazott DB-k a kötetmentésben",
|
"backups.beagyazott_db_k_a_kotetmentesben": "beágyazott DB-k a kötetmentésben",
|
||||||
"backups.elinditod_a_teljes_rendszermentest_most": "Elindítod a teljes rendszermentést most? A mentés alatt az alkalmazások leállnak — általában néhány perc, nagyobb adatnál több.",
|
"backups.elinditod_a_teljes_rendszermentest_most": "Elindítod a teljes rendszermentést most? A mentés alatt az alkalmazások leállnak — általában néhány perc, nagyobb adatnál több.",
|
||||||
"backups.mentes_inditasa": "Mentés indítása…",
|
"backups.mentes_inditasa": "Mentés indítása…",
|
||||||
"backups.hiba": "Hiba",
|
|
||||||
"backups.mentes_folyamatban": "Mentés folyamatban…",
|
"backups.mentes_folyamatban": "Mentés folyamatban…",
|
||||||
"backups.hiba_2": "Hiba:",
|
|
||||||
"backups.allapot": "Állapot:",
|
"backups.allapot": "Állapot:",
|
||||||
"backups.a_rendszermentes_elkeszult": "A rendszermentés elkészült.",
|
"backups.a_rendszermentes_elkeszult": "A rendszermentés elkészült.",
|
||||||
"backups.a_mentes_sikertelen": "A mentés sikertelen.",
|
"backups.a_mentes_sikertelen": "A mentés sikertelen.",
|
||||||
@@ -79,20 +89,15 @@
|
|||||||
"backups.a_meghajto_kijelolve_a_beallitas": "A meghajtó kijelölve. A beállítás a host-ügynök következő újraindulása után lép életbe.",
|
"backups.a_meghajto_kijelolve_a_beallitas": "A meghajtó kijelölve. A beállítás a host-ügynök következő újraindulása után lép életbe.",
|
||||||
"backups.a_meghajto_kijelolve": "A meghajtó kijelölve.",
|
"backups.a_meghajto_kijelolve": "A meghajtó kijelölve.",
|
||||||
"app_info.alkalmazasok": "← Alkalmazások",
|
"app_info.alkalmazasok": "← Alkalmazások",
|
||||||
"app_info.elavult": "Elavult",
|
|
||||||
"app_info.megnyitas": "Megnyitás ↗",
|
"app_info.megnyitas": "Megnyitás ↗",
|
||||||
"app_info.naplo": "Napló",
|
"app_info.naplo": "Napló",
|
||||||
"app_info.torles": "Törlés",
|
|
||||||
"app_info.exportalas": "Exportálás",
|
"app_info.exportalas": "Exportálás",
|
||||||
"app_info.beallitasok": "Beállítások",
|
"app_info.beallitasok": "Beállítások",
|
||||||
"app_info.telepites": "Telepítés",
|
"app_info.telepites": "Telepítés",
|
||||||
"app_info.mentesek": "Mentések",
|
"app_info.mentesek": "Mentések",
|
||||||
"app_info.hianyzo_tarhely": "Hiányzó tárhely:",
|
"app_info.hianyzo_tarhely": "Hiányzó tárhely:",
|
||||||
"app_info.ennek_az_alkalmazasnak_az_adattaroloja": "Ennek az alkalmazásnak az adattárolója jelenleg nem elérhető, ezért le van állítva. Csatlakoztasd újra a meghajtót, vagy helyezd át az adatokat egy másik tárhelyre.",
|
"app_info.ennek_az_alkalmazasnak_az_adattaroloja": "Ennek az alkalmazásnak az adattárolója jelenleg nem elérhető, ezért le van állítva. Csatlakoztasd újra a meghajtót, vagy helyezd át az adatokat egy másik tárhelyre.",
|
||||||
"app_info.hdd_szukseges": "HDD szükséges",
|
|
||||||
"app_info.pi_kompatibilis": "Pi kompatibilis",
|
|
||||||
"app_info.csak_x86": "Csak x86",
|
"app_info.csak_x86": "Csak x86",
|
||||||
"app_info.magyar_felulet": "Magyar felület",
|
|
||||||
"app_info.az_alkalmazas_fejlesztoje_felhagyott_a": "Az alkalmazás fejlesztője felhagyott a fejlesztéssel. A telepített verzió továbbra is használható,\n de frissítések és biztonsági javítások már nem érkeznek hozzá.",
|
"app_info.az_alkalmazas_fejlesztoje_felhagyott_a": "Az alkalmazás fejlesztője felhagyott a fejlesztéssel. A telepített verzió továbbra is használható,\n de frissítések és biztonsági javítások már nem érkeznek hozzá.",
|
||||||
"app_info.hova_tegyem_a_fajlokat": "Hova tegyem a fájlokat?",
|
"app_info.hova_tegyem_a_fajlokat": "Hova tegyem a fájlokat?",
|
||||||
"app_info.ezeket_a_mappakat_a_fajlkezeloben": "Ezeket a mappákat a Fájlkezelőben éred el. Előfordulhat, hogy először be kell jelentkezned a Fájlkezelőbe.",
|
"app_info.ezeket_a_mappakat_a_fajlkezeloben": "Ezeket a mappákat a Fájlkezelőben éred el. Előfordulhat, hogy először be kell jelentkezned a Fájlkezelőbe.",
|
||||||
@@ -113,14 +118,12 @@
|
|||||||
"app_info.athelyezed_a_z": "Áthelyezed a(z)",
|
"app_info.athelyezed_a_z": "Áthelyezed a(z)",
|
||||||
"app_info.adatait_ide": "adatait ide:",
|
"app_info.adatait_ide": "adatait ide:",
|
||||||
"app_info.az_alkalmazas_rovid_idore_leall": "? Az alkalmazás rövid időre leáll. A régi adatok csak sikeres áthelyezés után törlődnek.",
|
"app_info.az_alkalmazas_rovid_idore_leall": "? Az alkalmazás rövid időre leáll. A régi adatok csak sikeres áthelyezés után törlődnek.",
|
||||||
"app_info.hiba": "Hiba:",
|
|
||||||
"app_info.ismeretlen": "ismeretlen",
|
"app_info.ismeretlen": "ismeretlen",
|
||||||
"app_info.mire_hasznalhato": "Mire használható?",
|
"app_info.mire_hasznalhato": "Mire használható?",
|
||||||
"app_info.elso_lepesek": "Első lépések",
|
"app_info.elso_lepesek": "Első lépések",
|
||||||
"app_info.elofeltetelek": "Előfeltételek",
|
"app_info.elofeltetelek": "Előfeltételek",
|
||||||
"app_info.kezdeti_belepesi_adatok": "Kezdeti belépési adatok",
|
"app_info.kezdeti_belepesi_adatok": "Kezdeti belépési adatok",
|
||||||
"app_info.felhasznalonev": "Felhasználónév",
|
"app_info.felhasznalonev": "Felhasználónév",
|
||||||
"app_info.jelszo": "Jelszó",
|
|
||||||
"app_info.az_uzemelteto_allitotta_be": "az üzemeltető állította be",
|
"app_info.az_uzemelteto_allitotta_be": "az üzemeltető állította be",
|
||||||
"app_info.megjelenites": "Megjelenítés",
|
"app_info.megjelenites": "Megjelenítés",
|
||||||
"app_info.masolas": "Másolás",
|
"app_info.masolas": "Másolás",
|
||||||
@@ -169,7 +172,6 @@
|
|||||||
"layout.ez_az_alkalmazas_mar_telepitve": "Ez az alkalmazás már telepítve van.",
|
"layout.ez_az_alkalmazas_mar_telepitve": "Ez az alkalmazás már telepítve van.",
|
||||||
"layout.frissites": "↻ Frissítés...",
|
"layout.frissites": "↻ Frissítés...",
|
||||||
"layout.sablonok_frissitve": "Sablonok frissítve",
|
"layout.sablonok_frissitve": "Sablonok frissítve",
|
||||||
"layout.hiba": "Hiba:",
|
|
||||||
"layout.ismeretlen_hiba": "Ismeretlen hiba",
|
"layout.ismeretlen_hiba": "Ismeretlen hiba",
|
||||||
"layout.halozati_hiba": "Hálózati hiba:",
|
"layout.halozati_hiba": "Hálózati hiba:",
|
||||||
"layout.folyamatban": "Folyamatban...",
|
"layout.folyamatban": "Folyamatban...",
|
||||||
@@ -180,11 +182,7 @@
|
|||||||
"layout.alkalmazas_torlese": "Alkalmazás törlése:",
|
"layout.alkalmazas_torlese": "Alkalmazás törlése:",
|
||||||
"layout.ez_a_muvelet_eltavolitja_a": "Ez a művelet eltávolítja a konténereket, a köteteket és a konfigurációs fájlokat.",
|
"layout.ez_a_muvelet_eltavolitja_a": "Ez a művelet eltávolítja a konténereket, a köteteket és a konfigurációs fájlokat.",
|
||||||
"layout.ez_a_muvelet_nem_visszavonhato": "Ez a művelet nem visszavonható!",
|
"layout.ez_a_muvelet_nem_visszavonhato": "Ez a művelet nem visszavonható!",
|
||||||
"layout.megsem": "Mégsem",
|
|
||||||
"layout.torles": "Törlés",
|
|
||||||
"layout.hiba_2": "Hiba",
|
|
||||||
"layout.nem_sikerult_lekerni_az_adatokat": "Nem sikerült lekérni az adatokat:",
|
"layout.nem_sikerult_lekerni_az_adatokat": "Nem sikerült lekérni az adatokat:",
|
||||||
"layout.bezaras": "Bezárás",
|
|
||||||
"layout.torles_folyamatban": "Törlés folyamatban...",
|
"layout.torles_folyamatban": "Törlés folyamatban...",
|
||||||
"layout.torolt_adatok": "Törölt adatok:",
|
"layout.torolt_adatok": "Törölt adatok:",
|
||||||
"layout.megorzott_adatok": "Megőrzött adatok:",
|
"layout.megorzott_adatok": "Megőrzött adatok:",
|
||||||
@@ -202,7 +200,6 @@
|
|||||||
"layout.az_ejszakai_restic_pillanatkepek_nem": "Az éjszakai restic pillanatképek nem törölhetők egyenként — a megőrzési szabályok szerint automatikusan elavulnak.",
|
"layout.az_ejszakai_restic_pillanatkepek_nem": "Az éjszakai restic pillanatképek nem törölhetők egyenként — a megőrzési szabályok szerint automatikusan elavulnak.",
|
||||||
"layout.alkalmazas_eltavolitasa": "Alkalmazás eltávolítása:",
|
"layout.alkalmazas_eltavolitasa": "Alkalmazás eltávolítása:",
|
||||||
"layout.az_alkalmazas_visszaall_nincs_telepitve": "Az alkalmazás visszaáll \"Nincs telepítve\" állapotba. A sablon megmarad, újratelepíthető.",
|
"layout.az_alkalmazas_visszaall_nincs_telepitve": "Az alkalmazás visszaáll \"Nincs telepítve\" állapotba. A sablon megmarad, újratelepíthető.",
|
||||||
"layout.eltavolitas": "Eltávolítás",
|
|
||||||
"layout.eltavolitas_folyamatban": "Eltávolítás folyamatban...",
|
"layout.eltavolitas_folyamatban": "Eltávolítás folyamatban...",
|
||||||
"layout.torolt_mentesek": "Törölt mentések:",
|
"layout.torolt_mentesek": "Törölt mentések:",
|
||||||
"layout.nem_torolt_mentesek": "Nem törölt mentések:",
|
"layout.nem_torolt_mentesek": "Nem törölt mentések:",
|
||||||
@@ -233,5 +230,473 @@
|
|||||||
"func.restore_status.restoring": "Visszaállítás...",
|
"func.restore_status.restoring": "Visszaállítás...",
|
||||||
"func.restore_status.done": "Kész",
|
"func.restore_status.done": "Kész",
|
||||||
"func.restore_status.failed": "Sikertelen",
|
"func.restore_status.failed": "Sikertelen",
|
||||||
"func.restore_status.skipped": "Kihagyva"
|
"func.restore_status.skipped": "Kihagyva",
|
||||||
|
"dashboard.vezerlopult": "Vezérlőpult",
|
||||||
|
"dashboard.futo_alkalmazas": "Futó alkalmazás",
|
||||||
|
"dashboard.leallitva": "Leállítva",
|
||||||
|
"dashboard.osszes_alkalmazas": "Összes alkalmazás",
|
||||||
|
"dashboard.memoria": "Memória",
|
||||||
|
"dashboard.homerseklet": "Hőmérséklet",
|
||||||
|
"dashboard.nem_ismert": "nem ismert",
|
||||||
|
"dashboard.a_tarhely_merete_most_nem": "A tárhely mérete most nem olvasható ki.",
|
||||||
|
"dashboard.fogyoban_a_hely": "Fogyóban a hely",
|
||||||
|
"dashboard.kritikusan_keves_hely": "Kritikusan kevés hely",
|
||||||
|
"dashboard.lemezek_allapota": "Lemezek állapota",
|
||||||
|
"dashboard.nincs_adat": "Nincs adat",
|
||||||
|
"dashboard.biztonsagi_mentes": "Biztonsági mentés",
|
||||||
|
"dashboard.utolso_mentes": "Utolsó mentés:",
|
||||||
|
"dashboard.sikertelen": "Sikertelen",
|
||||||
|
"dashboard.meg_nem_futott": "Még nem futott",
|
||||||
|
"dashboard.adatbazisok": "Adatbázisok:",
|
||||||
|
"dashboard.mentve": "{{len .DBDumpStatus.Results}} mentve",
|
||||||
|
"dashboard.telepitett_alkalmazasok": "Telepített alkalmazások",
|
||||||
|
"dashboard.az_alkalmazas_adattaroloja_nem_elerheto": "Az alkalmazás adattárolója nem elérhető. Csatlakoztasd újra a meghajtót, vagy helyezd át az adatokat egy másik tárhelyre.",
|
||||||
|
"dashboard.hianyzo_tarhely": "Hiányzó tárhely: {{$ms}}",
|
||||||
|
"dashboard.az_alkalmazas_egyik_folyamatat_a": "Az alkalmazás egyik folyamatát a rendszer leállította, mert elfogyott a memóriája. Lehet, hogy egy feladat nem fejeződött be. Indítsd újra az alkalmazást; ha ismétlődik, jelezd az üzemeltetőnek.",
|
||||||
|
"dashboard.memoria_elfogyott": "Memória elfogyott",
|
||||||
|
"dashboard.az_alkalmazas_kornyezeteben_a_halozati": "Az alkalmazás környezetében a hálózati tárhely helyén üres helyi könyvtár van — az adatok nem a NAS-ra kerülnek. Jelezze az üzemeltetőnek.",
|
||||||
|
"dashboard.halozati_tarhely_hibas_az_alkalmazas": "Hálózati tárhely hibás — az alkalmazás nem a NAS-t látja",
|
||||||
|
"dashboard.a_halozati_tarhely_nas_jelenleg": "A hálózati tárhely (NAS) jelenleg nem érhető el. Az alkalmazás fut; az adatok elérése a NAS visszatértével helyreáll.",
|
||||||
|
"dashboard.halozati_tarhely_nem_elerheto": "Hálózati tárhely nem elérhető: {{$nw}}",
|
||||||
|
"dashboard.a_proxy_traefik_csak_egeszseges": "A proxy (Traefik) csak egészséges konténerhez publikál nyilvános útvonalat. Amíg az alkalmazás nem egészséges, az URL 404-et ad, pedig a konténer fut.",
|
||||||
|
"dashboard.url_nem_elerheto": "URL nem elérhető",
|
||||||
|
"dashboard.vedett": "Védett",
|
||||||
|
"dashboard.megnyitas": "Megnyitás",
|
||||||
|
"dashboard.telepites": "Telepítés",
|
||||||
|
"dashboard.leallitas": "Leállítás",
|
||||||
|
"dashboard.inditas": "Indítás",
|
||||||
|
"dashboard.naplo": "Napló",
|
||||||
|
"dashboard.nincs_elerheto_alkalmazas": "Nincs elérhető alkalmazás.",
|
||||||
|
"stacks.alkalmazasok": "Alkalmazások",
|
||||||
|
"stacks.alkalmazas_visszaallitasa_exportalt_csom": "Alkalmazás visszaállítása exportált csomagból",
|
||||||
|
"stacks.importalas": "Importálás",
|
||||||
|
"stacks.sablonok_frissitese_a_kozponti_katalogus": "Sablonok frissítése a központi katalógusból",
|
||||||
|
"stacks.sablonok_frissitese": "↻ Sablonok frissítése",
|
||||||
|
"stacks.futo": "Futó",
|
||||||
|
"stacks.leallitva": "Leállítva",
|
||||||
|
"stacks.telepitheto": "Telepíthető",
|
||||||
|
"stacks.a_proxy_traefik_csak_egeszseges": "A proxy (Traefik) csak egészséges konténerhez publikál nyilvános útvonalat. Amíg az alkalmazás nem egészséges, az URL nem érhető el (404), pedig a konténer fut.",
|
||||||
|
"stacks.url_nem_elerheto_utvonal_nincs": "URL nem elérhető – útvonal nincs publikálva",
|
||||||
|
"stacks.az_alkalmazas_adattaroloja_nem_elerheto": "Az alkalmazás adattárolója nem elérhető. Csatlakoztasd újra a meghajtót, vagy helyezd át az adatokat.",
|
||||||
|
"stacks.hianyzo_tarhely": "Hiányzó tárhely: {{$ms}}",
|
||||||
|
"stacks.az_alkalmazas_kornyezeteben_a_halozati": "Az alkalmazás környezetében a hálózati tárhely helyén üres helyi könyvtár van — az adatok nem a NAS-ra kerülnek. Jelezze az üzemeltetőnek.",
|
||||||
|
"stacks.halozati_tarhely_hibas_az_alkalmazas": "Hálózati tárhely hibás — az alkalmazás nem a NAS-t látja",
|
||||||
|
"stacks.a_halozati_tarhely_nas_jelenleg": "A hálózati tárhely (NAS) jelenleg nem érhető el. Az alkalmazás fut; az adatok elérése a NAS visszatértével helyreáll.",
|
||||||
|
"stacks.halozati_tarhely_nem_elerheto": "Hálózati tárhely nem elérhető: {{$nw}}",
|
||||||
|
"stacks.adattarolo": "Adattároló: {{index $.StorageLabels .Name}}",
|
||||||
|
"stacks.vedett_rendszerkomponens": "Védett rendszerkomponens",
|
||||||
|
"stacks.reszletek": "Részletek",
|
||||||
|
"stacks.telepites": "Telepítés",
|
||||||
|
"stacks.mentesek": "Mentések",
|
||||||
|
"stacks.frissites": "Frissítés",
|
||||||
|
"stacks.leallitas": "Leállítás",
|
||||||
|
"stacks.inditas": "Indítás",
|
||||||
|
"stacks.naplok": "Naplók",
|
||||||
|
"logs.vissza": "← Vissza",
|
||||||
|
"logs.naplok": "{{.Stack.Meta.DisplayName}} — Naplók",
|
||||||
|
"logs.elo": "Élő",
|
||||||
|
"logs.szuneteltetes": "Szüneteltetés",
|
||||||
|
"logs.frissites": "Frissítés",
|
||||||
|
"logs.szunetelve": "Szünetelve",
|
||||||
|
"logs.folytatas": "Folytatás",
|
||||||
|
"monitoring.rendszermonitor": "Rendszermonitor",
|
||||||
|
"monitoring.szerver_allapota_gazdagep": "Szerver állapota (gazdagép)",
|
||||||
|
"monitoring.a_gazdagep_metrikai_jelenleg_nem": "A gazdagép metrikái jelenleg nem elérhetők.",
|
||||||
|
"monitoring.cpu_hasznalat": "CPU használat",
|
||||||
|
"monitoring.terheles_load": "Terhelés (load)",
|
||||||
|
"monitoring.memoria": "Memória",
|
||||||
|
"monitoring.cpu_homerseklet": "CPU hőmérséklet",
|
||||||
|
"monitoring.uzemido": "Üzemidő",
|
||||||
|
"monitoring.tarolok_kapacitasa": "Tárolók kapacitása",
|
||||||
|
"monitoring.rendszer_attekintes": "Rendszer áttekintés",
|
||||||
|
"monitoring.gepnev": "Gépnév",
|
||||||
|
"monitoring.operacios_rendszer": "Operációs rendszer",
|
||||||
|
"monitoring.inditas": "Indítás",
|
||||||
|
"monitoring.tarhely": "Tárhely",
|
||||||
|
"monitoring.hub_kapcsolat": "Hub kapcsolat",
|
||||||
|
"monitoring.kapcsolodva_a_kozponti_rendszer_aktivan": "Kapcsolódva — a központi rendszer aktívan figyeli a szervert.",
|
||||||
|
"monitoring.nem_elerheto_a_kozponti_rendszer": "Nem elérhető — a központi rendszer nem kapott friss jelentést.",
|
||||||
|
"monitoring.utolso_sikeres_jelentes": "Utolsó sikeres jelentés",
|
||||||
|
"monitoring.utolso_hiba": "Utolsó hiba",
|
||||||
|
"monitoring.a_hub_kapcsolat_nincs_bekapcsolva": "A Hub kapcsolat nincs bekapcsolva — a központi monitoring nem aktív.",
|
||||||
|
"monitoring.rendszer_metrikak": "Rendszer metrikák",
|
||||||
|
"monitoring.1_ora": "1 óra",
|
||||||
|
"monitoring.6_ora": "6 óra",
|
||||||
|
"monitoring.24_ora": "24 óra",
|
||||||
|
"monitoring.7_nap": "7 nap",
|
||||||
|
"monitoring.30_nap": "30 nap",
|
||||||
|
"monitoring.cpu_hasznalat_2": "CPU használat (%)",
|
||||||
|
"monitoring.memoria_hasznalat_gb": "Memória használat (GB)",
|
||||||
|
"monitoring.homerseklet_c": "Hőmérséklet (°C)",
|
||||||
|
"monitoring.terheles_load_average": "Terhelés (Load Average)",
|
||||||
|
"monitoring.meg_nincsenek_adatok_a_metrikak": "Még nincsenek adatok. A metrikák gyűjtése elindult, az első adatok néhány perc múlva megjelennek.",
|
||||||
|
"monitoring.memoria_eloszlas": "Memória eloszlás",
|
||||||
|
"monitoring.alkalmazas_eroforrasok": "Alkalmazás erőforrások",
|
||||||
|
"monitoring.memoria_hasznalat_mb": "Memória használat (MB)",
|
||||||
|
"monitoring.meg_nincsenek_kontener_adatok": "Még nincsenek konténer adatok.",
|
||||||
|
"monitoring.memoria_mb": "Memória (MB)",
|
||||||
|
"monitoring.hasznalt": "Használt:",
|
||||||
|
"monitoring.rendszer_title": "Rendszer:",
|
||||||
|
"monitoring.rendszer_2": "Rendszer (",
|
||||||
|
"monitoring.szabad": "Szabad (",
|
||||||
|
"monitoring.eroforras_elozmenyek": "— Erőforrás előzmények",
|
||||||
|
"monitoring.nincs_tarolo_adat": "Nincs tároló adat.",
|
||||||
|
"monitoring.nem_elerheto": "Nem elérhető",
|
||||||
|
"monitoring.kopas": "kopás:",
|
||||||
|
"monitoring.frissitve": "Frissítve:",
|
||||||
|
"monitoring.nap": "nap,",
|
||||||
|
"monitoring.ora": "óra",
|
||||||
|
"monitoring.ora_2": "óra,",
|
||||||
|
"monitoring.perc": "perc",
|
||||||
|
"app_import.alkalmazasok": "← Alkalmazások",
|
||||||
|
"app_import.alkalmazas_importalas": "Alkalmazás importálás",
|
||||||
|
"app_import.fab_csomag_feltoltese_huzza_ide": ".fab csomag feltöltése — húzza ide, vagy válassza ki a fájlt",
|
||||||
|
"app_import.fajl_kivalasztasa": "Fájl kiválasztása",
|
||||||
|
"app_import.feltoltes_0": "Feltöltés: 0%",
|
||||||
|
"app_import.megszakitas": "Megszakítás",
|
||||||
|
"app_import.nem_talalhato_fab_csomag_a": "Nem található .fab csomag a regisztrált tárolókon.",
|
||||||
|
"app_import.exportalj_egy_alkalmazast_az_alkalmazas": "Exportálj egy alkalmazást az alkalmazás oldaláról, tölts fel egy .fab fájlt itt fent, vagy másolj egyet a <code>{tároló}/felhom-data/exports/</code> könyvtárba.",
|
||||||
|
"app_import.alkalmazas": "Alkalmazás",
|
||||||
|
"app_import.datum": "Dátum",
|
||||||
|
"app_import.meret": "Méret",
|
||||||
|
"app_import.tarolo": "Tároló",
|
||||||
|
"app_import.reszletek": "Részletek »",
|
||||||
|
"app_import.csomag_reszletei": "Csomag részletei",
|
||||||
|
"app_import.ez_a_csomag_jelszoval_vedett": "Ez a csomag jelszóval védett. Kérlek add meg a jelszót:",
|
||||||
|
"app_import.megnyitas": "Megnyitás",
|
||||||
|
"app_import.alkalmazas_2": "Alkalmazás:",
|
||||||
|
"app_import.exportalva": "Exportálva:",
|
||||||
|
"app_import.controller_verzio": "Controller verzió:",
|
||||||
|
"app_import.adatbazis": "Adatbázis:",
|
||||||
|
"app_import.adatok": "Adatok:",
|
||||||
|
"app_import.meret_2": "Méret:",
|
||||||
|
"app_import.figyelem_a_meglevo": "<strong>⚠ FIGYELEM:</strong> A meglévő",
|
||||||
|
"app_import.alkalmazas_konfiguracioja_es_osszes_adat": "alkalmazás konfigurációja és összes adata felül lesz írva!",
|
||||||
|
"app_import.visszaallitas_inditasa": "Visszaállítás indítása",
|
||||||
|
"app_import.importalas_folyamata": "Importálás folyamata",
|
||||||
|
"app_import.importalas_kesz": "Importálás kész!",
|
||||||
|
"app_import.az_alkalmazas_sikeresen_visszaallitva": "Az alkalmazás sikeresen visszaállítva.",
|
||||||
|
"app_import.alkalmazasok_megtekintese": "Alkalmazások megtekintése",
|
||||||
|
"app_import.hibas_jelszo": "Hibás jelszó",
|
||||||
|
"app_import.csomag_reszletei_2": "— Csomag részletei",
|
||||||
|
"app_import.nincs": "Nincs",
|
||||||
|
"app_import.alkalmazas_megtekintese": "Alkalmazás megtekintése",
|
||||||
|
"app_import.a_feltoltes_megszakadt_ellenorizze_a": "A feltöltés megszakadt — ellenőrizze a kapcsolatot, majd próbálja újra.",
|
||||||
|
"app_import.feltoltes": "Feltöltés:",
|
||||||
|
"app_import.csak_fab_fajl_toltheto_fel": "Csak .fab fájl tölthető fel.",
|
||||||
|
"app_import.feltoltes_kesz": "Feltöltés kész:",
|
||||||
|
"app_export.alkalmazasok": "← Alkalmazások",
|
||||||
|
"app_export.exportalas": "{{.Stack.Meta.DisplayName}} — Exportálás",
|
||||||
|
"app_export.mentes_helye": "Mentés helye",
|
||||||
|
"app_export.valassz_tarolot": "Válassz tárolót...",
|
||||||
|
"app_export.konfiguracio": "Konfiguráció:",
|
||||||
|
"app_export.felhasznaloi_adatok": "Felhasználói adatok:",
|
||||||
|
"app_export.osszesen": "Összesen:",
|
||||||
|
"app_export.szabad": "(szabad: -)",
|
||||||
|
"app_export.becsult_ido": "Becsült idő:",
|
||||||
|
"app_export.mindig_resze_a_mentesnek": "Mindig része a mentésnek:",
|
||||||
|
"app_export.valaszthato_tartalom": "Választható tartalom:",
|
||||||
|
"app_export.a_kihagyott_mappak_tartalma_a": "A kihagyott mappák tartalma a Fájlkezelőben bármikor elérhető, és külön is lementhető.",
|
||||||
|
"app_export.kihagyott_tartalom_megjelenitese": "Kihagyott tartalom megjelenítése",
|
||||||
|
"app_export.jelszo_opcionalis": "Jelszó (opcionális)",
|
||||||
|
"app_export.titkositasi_jelszo": "Titkosítási jelszó",
|
||||||
|
"app_export.jelszo_mutatasa": "Jelszó mutatása",
|
||||||
|
"app_export.alkalmazas_leallitasa_mentes_elott_ajanl": "Alkalmazás leállítása mentés előtt (ajánlott)",
|
||||||
|
"app_export.az_adatok_konzisztenciaja_erdekeben_java": "Az adatok konzisztenciája érdekében javasolt leállítani az alkalmazást mentés közben.",
|
||||||
|
"app_export.exportalas_inditasa": "Exportálás indítása",
|
||||||
|
"app_export.kesz": "Kész!",
|
||||||
|
"app_export.megnyitas_filebrowser_ben": "Megnyitás FileBrowser-ben ↗",
|
||||||
|
"app_export.szabad_2": "(szabad:",
|
||||||
|
"app_export.perc": "perc",
|
||||||
|
"app_export.nincs_eleg_szabad_hely_a": "Nincs elég szabad hely a kiválasztott tárolón!",
|
||||||
|
"app_export.alap_mentes": "Alap mentés: ~",
|
||||||
|
"app_export.a_kihagyott_nagy_meretu_tartalommal": ". A kihagyott, nagy méretű tartalommal együtt: ~",
|
||||||
|
"app_export.kihagyott_tartalom_elrejtese": "Kihagyott tartalom elrejtése",
|
||||||
|
"deploy.vissza": "← Vissza",
|
||||||
|
"deploy.beallitasok": "Beállítások",
|
||||||
|
"deploy.telepites": "Telepítés",
|
||||||
|
"deploy.leallitas": "Leállítás",
|
||||||
|
"deploy.inditas": "Indítás",
|
||||||
|
"deploy.megnyitas": "Megnyitás ↗",
|
||||||
|
"deploy.reszletek": "Részletek",
|
||||||
|
"deploy.reszletes_leiras_kepernyokepek": "Részletes leírás, képernyőképek",
|
||||||
|
"deploy.ez_az_alkalmazas_mar_telepitve": "Ez az alkalmazás már telepítve van. Az alábbi beállítások csak olvashatók.",
|
||||||
|
"deploy.adattarolas": "Adattárolás",
|
||||||
|
"deploy.tarhely": "Tárhely",
|
||||||
|
"deploy.adatmeret": "Adatméret",
|
||||||
|
"deploy.szabad_hely": "Szabad hely",
|
||||||
|
"deploy.szabad": "{{.StorageInfo.FreeHuman}} ({{printf \"%.0f\" .StorageInfo.FreePercent}}% szabad)",
|
||||||
|
"deploy.mozgatas_masik_tarolora": "Mozgatás másik tárolóra",
|
||||||
|
"deploy.korabbi_adatok": "Korábbi adatok",
|
||||||
|
"deploy.az_alkalmazas_adatainak_masolata_megtala": "Az alkalmazás adatainak másolata megtalálható egy másik tárolón is.\n Ez általában áthelyezés után marad hátra.",
|
||||||
|
"deploy.meret": "Méret",
|
||||||
|
"deploy.mappak": "Mappák",
|
||||||
|
"deploy.korabbi_adatok_torlese": "Korábbi adatok törlése",
|
||||||
|
"deploy.biztonsagi_mentes": "Biztonsági mentés",
|
||||||
|
"deploy.az_alkalmazas_adatbazisa_es_docker": "Az alkalmazás adatbázisa és Docker kötetei automatikusan bekerülnek az éjszakai biztonsági mentésbe.\n <a href=\"/backups\" style=\"color:var(--blue)\">Mentési állapot →</a> · <a href=\"/stacks/{{.Stack.Name}}/backup\" style=\"color:var(--blue)\">Mentési beállítások →</a>",
|
||||||
|
"deploy.integraciok": "Integrációk",
|
||||||
|
"deploy.mas_telepitett_alkalmazasokkal_valo_ossz": "Más telepített alkalmazásokkal való összekapcsolás. Az integráció automatikusan felfüggesztődik, ha bármelyik alkalmazás leáll, és újraaktiválódik indításkor.",
|
||||||
|
"deploy.nincs_telepitve": "Nincs telepítve",
|
||||||
|
"deploy.celalkalmazas_leallitva": "Célalkalmazás leállítva",
|
||||||
|
"deploy.aktiv": "Aktív",
|
||||||
|
"deploy.a_celalkalmazas_nincs_telepitve": "A célalkalmazás nincs telepítve",
|
||||||
|
"deploy.a_celalkalmazas_nem_fut": "A célalkalmazás nem fut",
|
||||||
|
"deploy.halozati_hiba": "Hálózati hiba",
|
||||||
|
"deploy.foldrajzi_korlatozas": "Földrajzi korlátozás",
|
||||||
|
"deploy.az_alkalmazas_egyeni_orszagkorlatozas_ne": "Az alkalmazás egyéni országkorlátozás nélkül a globális beállítást követi.",
|
||||||
|
"deploy.egyeni_orszagkorlatozas": "Egyéni országkorlátozás",
|
||||||
|
"deploy.engedelyezett_orszagok_ehhez_az_alkalmaz": "Engedélyezett országok ehhez az alkalmazáshoz",
|
||||||
|
"deploy.orszag_keresese": "Ország keresése...",
|
||||||
|
"deploy.mentes": "Mentés",
|
||||||
|
"deploy.nincs_talalat": "Nincs találat",
|
||||||
|
"deploy.mentve": "Mentve",
|
||||||
|
"deploy.opcionalis_beallitasok": "Opcionális beállítások",
|
||||||
|
"deploy.regisztracios_utmutato": "Regisztrációs útmutató ↗",
|
||||||
|
"deploy.mentes_2": "Mentés...",
|
||||||
|
"deploy.email_kuldes": "Email-küldés",
|
||||||
|
"deploy.ez_az_alkalmazas_tud_emailt": "Ez az alkalmazás tud emailt küldeni (pl. jelszó-visszaállítás, meghívók) a Felhom-on keresztül,\n külön szolgáltató beállítása nélkül. A feladó címe: <strong>{{.AppEmailFromAddress}}</strong>.",
|
||||||
|
"deploy.az_alkalmazas_email_jelenleg_ki": "Az alkalmazás-email jelenleg ki van kapcsolva globálisan. Kapcsold be a\n <a href=\"/settings\">Beállítások</a> oldalon, hogy itt is működjön.",
|
||||||
|
"deploy.email_kuldes_engedelyezese_ennel_az": "Email-küldés engedélyezése ennél az alkalmazásnál",
|
||||||
|
"deploy.a_mentes_ujrainditja_az_alkalmazast": "A mentés újraindítja az alkalmazást.",
|
||||||
|
"deploy.nincs_eleg_memoria_foglalas_telepites": "Nincs elég memória! Foglalás telepítés után: {{.AfterMB}} MB / {{.UsableMB}} MB",
|
||||||
|
"deploy.memoria": "Memória",
|
||||||
|
"deploy.jelenlegi_hasznalat_mb": "Jelenlegi használat: {{.UsedMB}} MB",
|
||||||
|
"deploy.jelenlegi_hasznalat_mb_2": "Jelenlegi használat ({{.UsedMB}} MB)",
|
||||||
|
"deploy.az_alkalmazasok_csucsterhelese_meghaladh": "Az alkalmazások csúcsterhelése meghaladhatja a rendelkezésre álló memóriát.\n Normál használat mellett ez nem okoz problémát.",
|
||||||
|
"deploy.ennek_az_alkalmazasnak_van_korabbi": "Ennek az alkalmazásnak van korábbi mentése, ezért az alábbi mezőket a saját mentése alapján töltöttük ki.",
|
||||||
|
"deploy.korabbi_webcim": "Korábbi webcím: <strong>{{.RestoreRecordedAddress}}</strong>.",
|
||||||
|
"deploy.ha_most_mashova_szeretned_telepiteni": "Ha most máshová szeretnéd telepíteni, nyugodtan átírhatod — a visszaállítás előtt jelezni fogjuk az eltérést.",
|
||||||
|
"deploy.az_alkalmazas_adatai_az_alabb": "Az alkalmazás adatai az alább kiválasztott adatmeghajtóra kerülnek.",
|
||||||
|
"deploy.hol_lesznek_az_adatok_ennel": "<strong>Hol lesznek az adatok:</strong> ennél az alkalmazásnál nincs külön adatmeghajtó-választás,\n ezért az adatai a rendszermeghajtóra kerülnek (<code>{{.SystemDataPath}}</code>). A mentései így is elkészülnek.",
|
||||||
|
"deploy.nincs_eleg_szabad_tarhely_a": "Nincs elég szabad tárhely a telepítéshez. Jelenleg {{.DockerFreeHuman}} szabad, és a rendszer\n {{.DockerReserveHuman}} tartalékot tart fenn az alapszolgáltatások (vezérlő, proxy) védelmében.\n A telepítés ezért átmenetileg le van tiltva — szabadítson fel helyet, vagy bővítse a tárhelyet.",
|
||||||
|
"deploy.automatikusan_generalt_ertekek": "Automatikusan generált értékek",
|
||||||
|
"deploy.ezek_az_ertekek_automatikusan_jottek": "Ezek az értékek automatikusan jöttek létre a telepítéskor.",
|
||||||
|
"deploy.ezek_az_ertekek_a_telepitessel": "Ezek az értékek a telepítéssel együtt mentésre kerülnek. Jegyezze fel a szükséges jelszavakat!",
|
||||||
|
"deploy.automatikusan_generalva": "Automatikusan generálva",
|
||||||
|
"deploy.megjelenites": "Megjelenítés",
|
||||||
|
"deploy.telepites_utan_nem_modosithato": "telepítés után nem módosítható",
|
||||||
|
"deploy.az_aldomain_telepites_utan_nem": "Az aldomain telepítés után nem módosítható. Megváltoztatáshoz az alkalmazás eltávolítása és újratelepítése szükséges (minden adat törlődik).",
|
||||||
|
"deploy.generalas": "Generálás",
|
||||||
|
"deploy.telepiteskor_beallitott_kezdeti_jelszo_h": "Telepítéskor beállított kezdeti jelszó — ha az alkalmazásban megváltoztattad, az itt nem frissül.",
|
||||||
|
"deploy.jelszo_megerositese": "Jelszó megerősítése",
|
||||||
|
"deploy.igen": "Igen",
|
||||||
|
"deploy.szabad_2": "{{.Label}} — {{.FreeHuman}} szabad",
|
||||||
|
"deploy.alapertelmezett": "(alapértelmezett)",
|
||||||
|
"deploy.nem_elerheto": "{{$.CurrentHDDPath}} (nem elérhető)",
|
||||||
|
"deploy.a_kivalasztott_tarhely_majdnem_megtelt": "A kiválasztott tárhely majdnem megtelt.",
|
||||||
|
"deploy.a_kivalasztott_meghajton_az_alkalmazas": "A kiválasztott meghajtón az alkalmazás <strong>fájljai</strong> (média, dokumentumok) tárolódnak.\n Az <strong>adatbázis a gyors belső SSD-n</strong> fut — és az alkalmazással együtt készül róla biztonsági mentés.",
|
||||||
|
"deploy.nincs_regisztralt_adattarolo_adja_meg": "Nincs regisztrált adattároló — adja meg kézzel az útvonalat",
|
||||||
|
"deploy.nincs_eleg_szabad_tarhely": "Nincs elég szabad tárhely",
|
||||||
|
"deploy.nincs_eleg_memoria": "Nincs elég memória",
|
||||||
|
"deploy.telepites_inditasa": "Telepítés indítása",
|
||||||
|
"deploy.telepites_folyamatban": "Telepítés folyamatban...",
|
||||||
|
"deploy.konfiguracio_mentese": "Konfiguráció mentése...",
|
||||||
|
"deploy.kontener_ek_inditasa": "Konténer(ek) indítása...",
|
||||||
|
"deploy.alkalmazas_inicializalasa": "Alkalmazás inicializálása...",
|
||||||
|
"deploy.alkalmazas_megnyitasa": "Alkalmazás megnyitása ↗",
|
||||||
|
"deploy.elso_lepesek": "Első lépések",
|
||||||
|
"deploy.masolas": "Másolás",
|
||||||
|
"deploy.bejelentkezes": "Bejelentkezés",
|
||||||
|
"deploy.dokumentacio": "Dokumentáció ↗",
|
||||||
|
"deploy.beallitasok_es_jelszavak_megtekintese": "Beállítások és jelszavak megtekintése",
|
||||||
|
"deploy.alkalmazasok": "← Alkalmazások",
|
||||||
|
"deploy.a_lekeres_nem_sikerult": "A lekérés nem sikerült.",
|
||||||
|
"deploy.elrejtes": "Elrejtés",
|
||||||
|
"deploy.masolva": "Másolva!",
|
||||||
|
"deploy.biztosan_torolni_szeretned_a_korabbi": "Biztosan törölni szeretnéd a korábbi adatokat? Tárhely:",
|
||||||
|
"deploy.figyelem_a_muvelet_visszavonhatatlan_elo": "— FIGYELEM: a művelet visszavonhatatlan! Előtte győződj meg róla, hogy az alkalmazás az új tárolóról megfelelően működik.",
|
||||||
|
"deploy.utolso_figyelmeztetes_a_torles_visszavon": "UTOLSÓ FIGYELMEZTETÉS! A törlés visszavonhatatlan. Biztosan folytatod?",
|
||||||
|
"deploy.torles_folyamatban": "Törlés folyamatban...",
|
||||||
|
"deploy.ismeretlen_hiba": "Ismeretlen hiba",
|
||||||
|
"deploy.korabbi_adatok_torolve_n_nfelszabaditott": "Korábbi adatok törölve!\\n\\nFelszabadított hely:",
|
||||||
|
"deploy.n_nnehany_hiba_tortent_n": "\\n\\nNéhány hiba történt:\\n",
|
||||||
|
"deploy.halozati_hiba_2": "Hálózati hiba:",
|
||||||
|
"deploy.kotelezo_mezo": "Kötelező mező:",
|
||||||
|
"deploy.nhasznalja_a_generalas_gombot_vagy": "\\nHasználja a Generálás gombot vagy írjon be egy jelszót.",
|
||||||
|
"deploy.a_ket_jelszo_nem_egyezik": "A két jelszó nem egyezik:",
|
||||||
|
"deploy.az_aldomain_csak_kisbetuket_szamokat": "Az aldomain csak kisbetűket, számokat és kötőjelet tartalmazhat, és nem kezdődhet/végződhet kötőjellel.",
|
||||||
|
"deploy.konfiguracio_mentve": "Konfiguráció mentve",
|
||||||
|
"deploy.masodperce": "másodperce...",
|
||||||
|
"deploy.idotullepes_az_alkalmazas_meg_indulhat": "Időtúllépés — az alkalmazás még indulhat",
|
||||||
|
"deploy.a_telepites_idotullepesbe_futott_az": "A telepítés időtúllépésbe futott. Az alkalmazás még indulhat.",
|
||||||
|
"deploy.telepites_sikertelen": "Telepítés sikertelen",
|
||||||
|
"deploy.a_telepites_nem_sikerult": "A telepítés nem sikerült:",
|
||||||
|
"deploy.naplok_megtekintese": "Naplók megtekintése",
|
||||||
|
"deploy.alkalmazasok_2": "Alkalmazások",
|
||||||
|
"deploy.kepek_letoltese_kontenerek_inditasa": "Képek letöltése, konténerek indítása...",
|
||||||
|
"deploy.kontenerek_elindultak": "Konténerek elindultak",
|
||||||
|
"deploy.alkalmazas_kesz": "Alkalmazás kész!",
|
||||||
|
"deploy.telepites_sikeres": "Telepítés sikeres!",
|
||||||
|
"deploy.az_alkalmazas_sikeresen_telepitve_es": "Az alkalmazás sikeresen telepítve és fut!",
|
||||||
|
"deploy.allapotjelzo_meg_inicializal": "Állapotjelző: még inicializál",
|
||||||
|
"deploy.az_alkalmazas_elindult_de_meg": "Az alkalmazás elindult, de még inicializálódik.",
|
||||||
|
"deploy.ez_normalis_az_elso_percekben": "Ez normális az első percekben — az alkalmazás már elérhető lehet.",
|
||||||
|
"deploy.a_kontener_leallt": "A konténer leállt",
|
||||||
|
"deploy.a_kontener_leallt_ellenorizze_a": "A konténer leállt. Ellenőrizze a naplókat.",
|
||||||
|
"settings_system.beallitasok_rendszer": "Beállítások — Rendszer",
|
||||||
|
"settings_system.rendszer_konfiguracio": "Rendszer konfiguráció",
|
||||||
|
"settings_system.az_uzemelteto_altal_beallitott_ertekek": "Az üzemeltető által beállított értékek. Módosításhoz kérd az üzemeltetőt.",
|
||||||
|
"settings_system.ugyfel_neve": "Ügyfél neve",
|
||||||
|
"settings_system.alkalmazas_sablon_forras": "Alkalmazás sablon forrás",
|
||||||
|
"settings_system.sablon_szinkronizalas": "Sablon szinkronizálás",
|
||||||
|
"settings_system.biztonsagi_mentes": "Biztonsági mentés",
|
||||||
|
"settings_system.aktiv": "Aktív",
|
||||||
|
"settings_system.inaktiv": "Inaktív",
|
||||||
|
"settings_system.mentes_utemezes": "Mentés ütemezés",
|
||||||
|
"settings_system.hub_jelentes": "Hub jelentés",
|
||||||
|
"settings_system.verzio_es_frissites": "Verzió és frissítés",
|
||||||
|
"settings_system.jelenlegi_verzio": "Jelenlegi verzió",
|
||||||
|
"settings_system.legujabb_verzio": "Legújabb verzió",
|
||||||
|
"settings_system.frissites_elerheto": "● Frissítés elérhető",
|
||||||
|
"settings_system.naprakesz": "— naprakész",
|
||||||
|
"settings_system.utolso_ellenorzes": "Utolsó ellenőrzés",
|
||||||
|
"settings_system.nyilvanos_hitelesites_nelkul": "nyilvános (hitelesítés nélkül)",
|
||||||
|
"settings_system.hitelesitett": "hitelesített",
|
||||||
|
"settings_system.automatikus_frissites": "Automatikus frissítés",
|
||||||
|
"settings_system.minimalis_verzio_uzemelteto": "Minimális verzió (üzemeltető)",
|
||||||
|
"settings_system.a_rendszer_automatikusan_erre_a": "— a rendszer automatikusan erre a verzióra frissít, ha régebbi",
|
||||||
|
"settings_system.allapot": "Állapot",
|
||||||
|
"settings_system.frissites_folyamatban_a_vezerlo_hamarosa": "Frissítés folyamatban — a vezérlő hamarosan újraindul…",
|
||||||
|
"settings_system.utolso_frissites": "Utolsó frissítés",
|
||||||
|
"settings_system.sikeres": "Sikeres",
|
||||||
|
"settings_system.sikertelen": "Sikertelen",
|
||||||
|
"settings_system.folyamatban": "Folyamatban",
|
||||||
|
"settings_system.frissites_keresese": "Frissítés keresése",
|
||||||
|
"settings_system.frissites_telepitese": "Frissítés telepítése",
|
||||||
|
"settings_system.halozat": "Hálózat",
|
||||||
|
"settings_system.helyi_cim_lan": "Helyi cím (LAN)",
|
||||||
|
"settings_system.nem_allapithato_meg": "nem állapítható meg",
|
||||||
|
"settings_system.halozati_nev": "Hálózati név",
|
||||||
|
"settings_system.atjaro": "Átjáró",
|
||||||
|
"settings_system.ezek_az_ertekek_a_helyi": "Ezek az értékek a helyi hálózattól függenek és változhatnak. Távoli hibaelhárításnál ezt az oldalt kérjük felolvasni.",
|
||||||
|
"settings_system.szerver_memoria_ram": "Szerver memória (RAM)",
|
||||||
|
"settings_system.jelenlegi_memoria": "Jelenlegi memória",
|
||||||
|
"settings_system.felhasznalt": "Felhasznált",
|
||||||
|
"settings_system.megengedett_tartomany": "Megengedett tartomány",
|
||||||
|
"settings_system.uj_meret_mb": "Új méret (MB)",
|
||||||
|
"settings_system.atmeretezes": "Átméretezés",
|
||||||
|
"settings_system.a_kiszolgalo_ugynok_jelenleg_nem": "A kiszolgáló ügynök jelenleg nem elérhető — próbáld meg később.",
|
||||||
|
"settings_system.a_memoria_atmeretezesehez_a_kiszolgalo": "A memória átméretezéséhez a kiszolgáló rendszerfrissítése szükséges.",
|
||||||
|
"settings_system.megerosites": "Megerősítés",
|
||||||
|
"settings_system.ellenorzes": "Ellenőrzés...",
|
||||||
|
"settings_system.kapcsolodasi_hiba": "Kapcsolódási hiba",
|
||||||
|
"settings_system.vezerlo_frissitese": "Vezérlő frissítése",
|
||||||
|
"settings_system.frissites": "Frissítés",
|
||||||
|
"settings_system.biztosan_frissiti_a_controllert_n": "Biztosan frissíti a controllert?\\n\\nA folyamat alatt a vezérlőpult rövid időre elérhetetlenné válik.",
|
||||||
|
"settings_system.frissites_2": "Frissítés...",
|
||||||
|
"settings_system.frissites_folyamatban": "Frissítés folyamatban...",
|
||||||
|
"settings_system.ujraindulas": "Újraindulás...",
|
||||||
|
"settings_system.ervenytelen_memoria_ertek": "Érvénytelen memória érték",
|
||||||
|
"settings_system.memoria_csokkentese": "Memória csökkentése",
|
||||||
|
"settings_system.csokkentes": "Csökkentés",
|
||||||
|
"settings_system.a_memoria_csokkentese_hatassal_lehet": "A memória csökkentése hatással lehet a futó alkalmazások teljesítményére. Biztosan folytatod?",
|
||||||
|
"settings_system.atmeretezes_2": "Átméretezés...",
|
||||||
|
"settings_system.kesz": "Kész.",
|
||||||
|
"settings_system.a_muvelet_nem_sikerult": "A művelet nem sikerült",
|
||||||
|
"settings_system.vezerlo_ujrainditasa": "Vezérlő újraindítása",
|
||||||
|
"settings_system.ha_a_vezerlo_hibasan_mukodik": "Ha a vezérlő hibásan működik, itt biztonságosan újraindíthatja — nem kell az egész szervert újraindítani.\n Az alkalmazásai futnak tovább; csak a vezérlő indul újra (néhány másodperc).",
|
||||||
|
"settings_system.kiszolgalo_ujrainditasa": "Kiszolgáló újraindítása",
|
||||||
|
"settings_system.az_egesz_kiszolgalo_szerver_ujrainditasa": "Az egész kiszolgáló (szerver) újraindítása. Minden alkalmazás rövid időre leáll, és a vezérlőpult kb. 30 másodpercig nem elérhető. Akkor használja, ha a teljes rendszer újraindítására van szükség — egyébként a fenti „Vezérlő újraindítása” elegendő.",
|
||||||
|
"settings_system.biztosan_ujrainditja_a_vezerlot_a": "Biztosan újraindítja a vezérlőt? A művelet néhány másodpercig tart, és a felület rövid időre elérhetetlen lesz.",
|
||||||
|
"settings_system.ujrainditas_folyamatban_ujracsatlakozas": "Újraindítás folyamatban… újracsatlakozás…",
|
||||||
|
"settings_system.biztosan_ujrainditja_a_kiszolgalot_az": "Biztosan újraindítja a kiszolgálót? Az alkalmazások és a vezérlőpult kb. 30 másodpercre elérhetetlenné válnak.",
|
||||||
|
"settings_system.ujrainditas_folyamatban_a_vezerlopult_ne": "Újraindítás folyamatban… a vezérlőpult néhány másodperc múlva újratölt.",
|
||||||
|
"settings_system.az_ujrainditas_a_vartnal_tovabb": "Az újraindítás a vártnál tovább tart. Töltse újra az oldalt kézzel.",
|
||||||
|
"settings_security.beallitasok_biztonsag_es_hozzaferes": "Beállítások — Biztonság és hozzáférés",
|
||||||
|
"settings_security.jelszo_modositas": "Jelszó módosítás",
|
||||||
|
"settings_security.jelenlegi_jelszo": "Jelenlegi jelszó",
|
||||||
|
"settings_security.adja_meg_a_jelenlegi_jelszavat": "Adja meg a jelenlegi jelszavát",
|
||||||
|
"settings_security.uj_jelszo": "Új jelszó",
|
||||||
|
"settings_security.legalabb_8_karakter": "Legalább 8 karakter",
|
||||||
|
"settings_security.uj_jelszo_megerositese": "Új jelszó megerősítése",
|
||||||
|
"settings_security.jelszo_megegyszer": "Jelszó mégegyszer",
|
||||||
|
"settings_security.jelszo_modositasa": "Jelszó módosítása",
|
||||||
|
"settings_security.a_jelszavas_vedelem_nincs_beallitva": "A jelszavas védelem nincs beállítva. Kérd az üzemeltetőt a beállításhoz.",
|
||||||
|
"settings_security.foldrajzi_korlatozas": "Földrajzi korlátozás",
|
||||||
|
"settings_security.orszag_alapjan_korlatozhato_a_webes": "Ország alapján korlátozható a webes alkalmazások elérése a Cloudflare WAF segítségével.",
|
||||||
|
"settings_security.a_helyi_halozati_hozzaferes_mindig": "A helyi hálózati hozzáférés mindig engedélyezett (nem halad át a Cloudflare-en).",
|
||||||
|
"settings_security.a_cloudflare_api_token_nincs": "A Cloudflare API token nincs konfigurálva. Kérd az üzemeltetőt a beállításhoz.<br>\n <small>A tokennek <strong>Zone WAF:Edit</strong> jogosultsággal kell rendelkeznie.</small>",
|
||||||
|
"settings_security.geo_korlatozas_aktiv": "Geo-korlátozás aktív",
|
||||||
|
"settings_security.engedelyezett_orszagok_globalis": "Engedélyezett országok (globális)",
|
||||||
|
"settings_security.orszag_keresese": "Ország keresése...",
|
||||||
|
"settings_security.csak_a_kivalasztott_orszagokbol_erheto": "Csak a kiválasztott országokból érhető el a rendszer.",
|
||||||
|
"settings_security.alkalmazas_specifikus_felulirasok": "Alkalmazás-specifikus felülírások",
|
||||||
|
"settings_security.alkalmazas_kivalasztasa": "— Alkalmazás kiválasztása —",
|
||||||
|
"settings_security.hozzaadas": "+ Hozzáadás",
|
||||||
|
"settings_security.mentes_es_szinkronizalas": "Mentés és szinkronizálás",
|
||||||
|
"settings_security.kezi_szinkronizalas": "Kézi szinkronizálás",
|
||||||
|
"settings_security.utolso_szinkronizalas": "Utolsó szinkronizálás: {{.GeoLastSync}}",
|
||||||
|
"settings_security.megerosites": "Megerősítés",
|
||||||
|
"settings_security.nincs_talalat": "Nincs találat",
|
||||||
|
"settings_security.figyelem_magyarorszag_eltavolitasa_azt_j": "Figyelem: Magyarország eltávolítása azt jelenti, hogy magyar IP-ről sem lesz elérhető a rendszer távolról. Biztosan folytatja?",
|
||||||
|
"settings_security.magyarorszag_eltavolitasa_nem_ajanlott_f": "Magyarország eltávolítása nem ajánlott. Folytatja?",
|
||||||
|
"settings_security.nincs_alkalmazas_specifikus_beallitas_mi": "Nincs alkalmazás-specifikus beállítás. Minden alkalmazás a globális beállítást követi.",
|
||||||
|
"settings_security.szerkesztes": "Szerkesztés",
|
||||||
|
"settings_security.engedelyezett_orszagok": "Engedélyezett országok:",
|
||||||
|
"settings_security.kesz": "Kész",
|
||||||
|
"settings_security.mentes": "Mentés...",
|
||||||
|
"settings_security.mentve": "Mentve",
|
||||||
|
"settings_security.halozati_hiba": "Hálózati hiba",
|
||||||
|
"settings_security.szinkronizalas_elinditva": "Szinkronizálás elindítva...",
|
||||||
|
"settings_security.utolso": "Utolsó:",
|
||||||
|
"settings_security.veszhelyzeti_informaciok": "Vészhelyzeti információk",
|
||||||
|
"settings_security.ezeket_az_adatokat_mentse_el": "Ezeket az adatokat mentse el biztos helyre. Újratelepítés esetén szükség lesz rájuk a rendszer visszaállításához.",
|
||||||
|
"settings_security.visszaallitasi_jelszo": "Visszaállítási jelszó",
|
||||||
|
"settings_security.megjelenit": "Megjelenít",
|
||||||
|
"settings_security.tamogatas": "Támogatás",
|
||||||
|
"settings_security.felhom_eu_kapcsolat": "<a href=\"mailto:{{.SupportEmail}}\" style=\"color: var(--blue);\">{{.SupportEmail}}</a>\n | \n <a href=\"{{.SupportURL}}\" target=\"_blank\" style=\"color: var(--blue);\">felhom.eu/kapcsolat</a>",
|
||||||
|
"settings_security.a_visszaallitasi_jelszo_lekerese_nem": "A visszaállítási jelszó lekérése nem sikerült.",
|
||||||
|
"settings_security.elrejt": "Elrejt",
|
||||||
|
"settings_notifications.beallitasok_ertesitesek": "Beállítások — Értesítések",
|
||||||
|
"settings_notifications.ertesitesek": "Értesítések",
|
||||||
|
"settings_notifications.e_mail_cim": "E-mail cím",
|
||||||
|
"settings_notifications.hibak_es_figyelmeztetesek": "Hibák és figyelmeztetések:",
|
||||||
|
"settings_notifications.biztonsagi_mentes_sikertelen": "Biztonsági mentés sikertelen",
|
||||||
|
"settings_notifications.adatbazis_mentes_sikertelen": "Adatbázis mentés sikertelen",
|
||||||
|
"settings_notifications.mentes_serules_eszlelve": "Mentés sérülés észlelve",
|
||||||
|
"settings_notifications.masodlagos_mentes_sikertelen": "Másodlagos mentés sikertelen",
|
||||||
|
"settings_notifications.tavoli_mentes_tarhelykeret_figyelmeztete": "Távoli mentés — tárhelykeret-figyelmeztetés",
|
||||||
|
"settings_notifications.lemez_beteloben_90_felett": "Lemez betelőben (90% felett)",
|
||||||
|
"settings_notifications.lemez_megtelt_vagy_meghibasodott": "Lemez megtelt vagy meghibásodott",
|
||||||
|
"settings_notifications.meghajto_levalasztva": "Meghajtó leválasztva",
|
||||||
|
"settings_notifications.szerver_nem_elerheto": "Szerver nem elérhető",
|
||||||
|
"settings_notifications.rendszer_allapot_kritikus": "Rendszer állapot kritikus",
|
||||||
|
"settings_notifications.elvart_fajlmentes_elmaradt": "Elvárt fájlmentés elmaradt",
|
||||||
|
"settings_notifications.elvart_adatbazismentes_elmaradt": "Elvárt adatbázismentés elmaradt",
|
||||||
|
"settings_notifications.alkalmazas_nem_fut": "Alkalmazás nem fut",
|
||||||
|
"settings_notifications.tajekoztato": "Tájékoztató:",
|
||||||
|
"settings_notifications.meghajto_ujra_csatlakoztatva": "Meghajtó újra csatlakoztatva",
|
||||||
|
"settings_notifications.rendszer_allapot_helyreallt": "Rendszer állapot helyreállt",
|
||||||
|
"settings_notifications.ertesitesi_szunet": "Értesítési szünet",
|
||||||
|
"settings_notifications.ora_azonos_problema_eseten_ennyi": "óra (azonos probléma esetén ennyi ideig nem küld újat)",
|
||||||
|
"settings_notifications.mentes": "Mentés",
|
||||||
|
"settings_notifications.teszt_email_kuldese": "Teszt email küldése",
|
||||||
|
"settings_notifications.az_ertesitesek_a_kozponti_rendszeren": "Az értesítések a központi rendszeren keresztül működnek, ami jelenleg nincs bekapcsolva.",
|
||||||
|
"settings_notifications.alkalmazas_email": "Alkalmazás-email",
|
||||||
|
"settings_notifications.az_alkalmazasok_a_felhom_on": "Az alkalmazások a Felhom-on keresztül küldhetnek emailt (pl. jelszó-visszaállítás, meghívók),\n külön email-szolgáltató beállítása nélkül. A feladó címe minden alkalmazásnál a saját\n <em><alkalmazás>@felhom.eu</em> címe lesz.",
|
||||||
|
"settings_notifications.alkalmazas_email_engedelyezese": "Alkalmazás-email engedélyezése",
|
||||||
|
"settings_notifications.felado_neve_opcionalis": "Feladó neve (opcionális)",
|
||||||
|
"settings_notifications.pl_a_haztartas_neve": "pl. a háztartás neve",
|
||||||
|
"settings_notifications.ez_jelenik_meg_a_kimeno": "Ez jelenik meg a kimenő emailek feladójaként az alkalmazás neve mellett.",
|
||||||
|
"settings_notifications.bekapcsolas_utan_az_egyes_alkalmazasokna": "Bekapcsolás után az egyes alkalmazásoknál is engedélyezni kell az email-küldést (az alkalmazás oldalán).",
|
||||||
|
"stacks.mind": "Mind",
|
||||||
|
"app_export.folyamat": "Folyamat",
|
||||||
|
"app_import.titkos": "Titkos",
|
||||||
|
"monitoring.processzor": "Processzor",
|
||||||
|
"deploy.hamarosan": "Hamarosan",
|
||||||
|
"deploy.az_adatai_itt_voltak": "Az adatai itt voltak: <strong>{{.RestoreRecordedDrive}}</strong>.",
|
||||||
|
"deploy.aldomain_placeholder": "aldomain",
|
||||||
|
"settings_security.figyelem": "Figyelem",
|
||||||
|
"settings_notifications.pelda_email": "pelda@email.hu",
|
||||||
|
"page.title.dashboard": "Vezérlőpult",
|
||||||
|
"page.title.stacks": "Alkalmazások",
|
||||||
|
"page.title.monitoring": "Rendszermonitor",
|
||||||
|
"page.title.settings": "Beállítások",
|
||||||
|
"page.title.settings_notifications": "Értesítések",
|
||||||
|
"page.title.settings_security": "Biztonság és hozzáférés",
|
||||||
|
"func.infra.cloudflared.description": "Biztonságos internetkapcsolat — a szerver portnyitás nélkül érhető el kívülről.",
|
||||||
|
"func.infra.traefik.description": "Forgalomirányító (reverse proxy) — a kéréseket a megfelelő alkalmazáshoz irányítja.",
|
||||||
|
"func.infra.filebrowser.description": "Fájlkezelő — a tárhely fájljainak böngészése a böngészőből.",
|
||||||
|
"func.infra.samba.display": "Hálózati megosztás",
|
||||||
|
"func.infra.samba.description": "Fájlmegosztás a helyi hálózaton — a mappák a Windows Intézőben és a Mac Finderben jelennek meg."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
// now hit twice (R-262, and the OOB fixture in hub v0.99.0).
|
// now hit twice (R-262, and the OOB fixture in hub v0.99.0).
|
||||||
func diskMeterBlock(t *testing.T) string {
|
func diskMeterBlock(t *testing.T) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
raw, err := templateFS.ReadFile("templates/dashboard.html")
|
raw, err := huTemplateSource("templates/dashboard.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("read dashboard.html: %v", err)
|
t.Fatalf("read dashboard.html: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ func (s *Server) dashboardHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
sysInfo := system.GetInfo(s.primaryHDDPath(), s.cpuCollector)
|
sysInfo := system.GetInfo(s.primaryHDDPath(), s.cpuCollector)
|
||||||
|
|
||||||
data := s.baseData("dashboard", "Vezérlőpult")
|
data := s.baseData("dashboard", "Vezérlőpult")
|
||||||
|
data["TitleKey"] = "page.title.dashboard" // i18n: the Hungarian title above is what hu renders
|
||||||
s.addRecoveryBanner(data, r) // R-241: the reminder bar, per visit
|
s.addRecoveryBanner(data, r) // R-241: the reminder bar, per visit
|
||||||
data["SettingsWarning"] = s.settings.LoadWarning // non-empty if settings.json was recovered from corruption
|
data["SettingsWarning"] = s.settings.LoadWarning // non-empty if settings.json was recovered from corruption
|
||||||
data["Stacks"] = deployedStacks
|
data["Stacks"] = deployedStacks
|
||||||
@@ -356,6 +357,7 @@ func visibleCatalogStacks(in []stacks.Stack) []stacks.Stack {
|
|||||||
|
|
||||||
func (s *Server) stacksHandler(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) stacksHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
data := s.baseData("stacks", "Alkalmazások")
|
data := s.baseData("stacks", "Alkalmazások")
|
||||||
|
data["TitleKey"] = "page.title.stacks" // i18n: the Hungarian title above is what hu renders
|
||||||
allStacks := visibleCatalogStacks(s.stackMgr.GetStacks())
|
allStacks := visibleCatalogStacks(s.stackMgr.GetStacks())
|
||||||
data["Stacks"] = allStacks
|
data["Stacks"] = allStacks
|
||||||
data["MissingStorage"] = s.missingStorageMap(allStacks)
|
data["MissingStorage"] = s.missingStorageMap(allStacks)
|
||||||
@@ -793,6 +795,7 @@ func (s *Server) appDetailHandler(w http.ResponseWriter, r *http.Request, slug s
|
|||||||
|
|
||||||
func (s *Server) monitoringHandler(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) monitoringHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
data := s.baseData("monitoring", "Rendszermonitor")
|
data := s.baseData("monitoring", "Rendszermonitor")
|
||||||
|
data["TitleKey"] = "page.title.monitoring" // i18n: the Hungarian title above is what hu renders
|
||||||
data["SystemInfo"] = system.GetInfo(s.primaryHDDPath(), s.cpuCollector)
|
data["SystemInfo"] = system.GetInfo(s.primaryHDDPath(), s.cpuCollector)
|
||||||
data["StorageBars"] = s.buildStorageBars()
|
data["StorageBars"] = s.buildStorageBars()
|
||||||
|
|
||||||
@@ -2043,6 +2046,7 @@ func (s *Server) settingsBaseData(page, title string) map[string]interface{} {
|
|||||||
// controller + server restart.
|
// controller + server restart.
|
||||||
func (s *Server) systemPageData() map[string]interface{} {
|
func (s *Server) systemPageData() map[string]interface{} {
|
||||||
data := s.settingsBaseData("settings", "Beállítások")
|
data := s.settingsBaseData("settings", "Beállítások")
|
||||||
|
data["TitleKey"] = "page.title.settings" // i18n: the Hungarian title above is what hu renders
|
||||||
data["GitRepoURL"] = s.cfg.Git.RepoURL
|
data["GitRepoURL"] = s.cfg.Git.RepoURL
|
||||||
data["GitSyncInterval"] = s.cfg.Git.SyncInterval
|
data["GitSyncInterval"] = s.cfg.Git.SyncInterval
|
||||||
data["BackupEnabled"] = s.cfg.Backup.Enabled
|
data["BackupEnabled"] = s.cfg.Backup.Enabled
|
||||||
@@ -2157,6 +2161,7 @@ func (s *Server) networkStoragePageData() map[string]interface{} {
|
|||||||
// notificationsPageData builds the Értesítések subpage: notification prefs + app-email.
|
// notificationsPageData builds the Értesítések subpage: notification prefs + app-email.
|
||||||
func (s *Server) notificationsPageData() map[string]interface{} {
|
func (s *Server) notificationsPageData() map[string]interface{} {
|
||||||
data := s.settingsBaseData("settings-notifications", "Értesítések")
|
data := s.settingsBaseData("settings-notifications", "Értesítések")
|
||||||
|
data["TitleKey"] = "page.title.settings_notifications" // i18n: the Hungarian title above is what hu renders
|
||||||
data["HubEnabled"] = s.cfg.Hub.Enabled
|
data["HubEnabled"] = s.cfg.Hub.Enabled
|
||||||
data["NotificationPrefs"] = s.settings.GetNotificationPrefs()
|
data["NotificationPrefs"] = s.settings.GetNotificationPrefs()
|
||||||
|
|
||||||
@@ -2173,6 +2178,7 @@ func (s *Server) notificationsPageData() map[string]interface{} {
|
|||||||
// emergency/recovery info.
|
// emergency/recovery info.
|
||||||
func (s *Server) securityPageData() map[string]interface{} {
|
func (s *Server) securityPageData() map[string]interface{} {
|
||||||
data := s.settingsBaseData("settings-security", "Biztonság és hozzáférés")
|
data := s.settingsBaseData("settings-security", "Biztonság és hozzáférés")
|
||||||
|
data["TitleKey"] = "page.title.settings_security" // i18n: the Hungarian title above is what hu renders
|
||||||
|
|
||||||
// Recovery info for emergency section.
|
// Recovery info for emergency section.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import (
|
|||||||
// TestI18nParity fails naming the page and the first differing line.
|
// TestI18nParity fails naming the page and the first differing line.
|
||||||
|
|
||||||
var updateI18nGolden = flag.Bool("update-i18n-golden", false, "write MISSING testdata/i18n_parity fixtures from the current templates (an existing fixture is never overwritten)")
|
var updateI18nGolden = flag.Bool("update-i18n-golden", false, "write MISSING testdata/i18n_parity fixtures from the current templates (an existing fixture is never overwritten)")
|
||||||
|
var i18nDumpDir = flag.String("i18n-dump-dir", "", "TestI18nEnglishPages: also write every case's hu and en render to this directory (evidence, per-page review)")
|
||||||
var i18nGoldenOnly = flag.String("i18n-golden-only", "", "with -update-i18n-golden: only cases whose name matches this regexp")
|
var i18nGoldenOnly = flag.String("i18n-golden-only", "", "with -update-i18n-golden: only cases whose name matches this regexp")
|
||||||
|
|
||||||
var relativeAgeRe = regexp.MustCompile(`\d+ (napja|órája|perce)`)
|
var relativeAgeRe = regexp.MustCompile(`\d+ (napja|órája|perce)`)
|
||||||
@@ -52,6 +53,12 @@ func i18nFixtureTime() time.Time { return time.Date(2026, 9, 14, 3, 12, 0, 0, ti
|
|||||||
var i18nTitleKeys = map[string]string{
|
var i18nTitleKeys = map[string]string{
|
||||||
"Indítópult": "page.title.launcher",
|
"Indítópult": "page.title.launcher",
|
||||||
"Biztonsági mentés": "page.title.backups",
|
"Biztonsági mentés": "page.title.backups",
|
||||||
|
"Vezérlőpult": "page.title.dashboard",
|
||||||
|
"Alkalmazások": "page.title.stacks",
|
||||||
|
"Rendszermonitor": "page.title.monitoring",
|
||||||
|
"Beállítások": "page.title.settings",
|
||||||
|
"Értesítések": "page.title.settings_notifications",
|
||||||
|
"Biztonság és hozzáférés": "page.title.settings_security",
|
||||||
}
|
}
|
||||||
|
|
||||||
func i18nLayoutData(page, title string) map[string]interface{} {
|
func i18nLayoutData(page, title string) map[string]interface{} {
|
||||||
@@ -376,7 +383,7 @@ func fixtureStrings(v reflect.Value, out map[string]bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var i18nKeyLikeRe = regexp.MustCompile(`\b(launcher|backups|backups_shared|app_info|layout|func)\.[a-z0-9_]+\b`)
|
var i18nKeyLikeRe = regexp.MustCompile(`\b[a-z][a-z_]*\.[a-z0-9_.]+\b`)
|
||||||
var emptyElemRe = regexp.MustCompile(`<(h[1-6]|button|label|li|strong|option|p)(\s[^>]*)?>\s*</(h[1-6]|button|label|li|strong|option|p)>`)
|
var emptyElemRe = regexp.MustCompile(`<(h[1-6]|button|label|li|strong|option|p)(\s[^>]*)?>\s*</(h[1-6]|button|label|li|strong|option|p)>`)
|
||||||
|
|
||||||
// TestI18nEnglishPages — the three pages in English: no Hungarian letter from the TEMPLATE copy, no
|
// TestI18nEnglishPages — the three pages in English: no Hungarian letter from the TEMPLATE copy, no
|
||||||
@@ -395,14 +402,22 @@ func TestI18nEnglishPages(t *testing.T) {
|
|||||||
for _, c := range i18nCases() {
|
for _, c := range i18nCases() {
|
||||||
hu := renderI18nCase(t, s, "hu", c)
|
hu := renderI18nCase(t, s, "hu", c)
|
||||||
en := renderI18nCase(t, s, "en", c)
|
en := renderI18nCase(t, s, "en", c)
|
||||||
|
if *i18nDumpDir != "" {
|
||||||
|
_ = os.MkdirAll(*i18nDumpDir, 0o755)
|
||||||
|
_ = os.WriteFile(filepath.Join(*i18nDumpDir, c.name+".hu.html"), []byte(hu), 0o644)
|
||||||
|
_ = os.WriteFile(filepath.Join(*i18nDumpDir, c.name+".en.html"), []byte(en), 0o644)
|
||||||
|
}
|
||||||
if !huLetter(hu) {
|
if !huLetter(hu) {
|
||||||
t.Fatalf("%s: positive control failed — the Hungarian render carries no Hungarian letter", c.name)
|
t.Fatalf("%s: positive control failed — the Hungarian render carries no Hungarian letter", c.name)
|
||||||
}
|
}
|
||||||
if strings.Contains(en, `{{T `) {
|
if strings.Contains(en, `{{T `) {
|
||||||
t.Errorf("%s: an unexpanded marker reached the English page", c.name)
|
t.Errorf("%s: an unexpanded marker reached the English page", c.name)
|
||||||
}
|
}
|
||||||
if m := i18nKeyLikeRe.FindString(en); m != "" && s.i18n.Has(i18n.Default, m) {
|
for _, m := range i18nKeyLikeRe.FindAllString(en, -1) {
|
||||||
t.Errorf("%s: a raw bundle key reached the English page: %q", c.name, m)
|
if s.i18n.Has(i18n.Default, m) {
|
||||||
|
t.Errorf("%s: a raw bundle key reached the English page: %q", c.name, m)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if a, b := len(emptyElemRe.FindAllString(hu, -1)), len(emptyElemRe.FindAllString(en, -1)); b > a {
|
if a, b := len(emptyElemRe.FindAllString(hu, -1)), len(emptyElemRe.FindAllString(en, -1)); b > a {
|
||||||
t.Errorf("%s: English has %d empty elements, Hungarian %d — a translation rendered blank", c.name, b, a)
|
t.Errorf("%s: English has %d empty elements, Hungarian %d — a translation rendered blank", c.name, b, a)
|
||||||
|
|||||||
@@ -129,6 +129,22 @@ func (s *Server) localeFuncs(lang string) template.FuncMap {
|
|||||||
}
|
}
|
||||||
return lt.Format("2006-01-02") + " " + hm
|
return lt.Format("2006-01-02") + " " + hm
|
||||||
},
|
},
|
||||||
|
// infraMeta: the protected infra stacks' curated identity (inframeta.go). Names that are product
|
||||||
|
// names stay; descriptions — and samba's display name — come from the bundle.
|
||||||
|
"infraMeta": func(name string) *InfraMeta {
|
||||||
|
m := infraMetaFor(name)
|
||||||
|
if m == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := *m
|
||||||
|
if v, _, ok := b.Text(lang, "func.infra."+name+".description"); ok {
|
||||||
|
out.Description = v
|
||||||
|
}
|
||||||
|
if v, _, ok := b.Text(lang, "func.infra."+name+".display"); ok {
|
||||||
|
out.DisplayName = v
|
||||||
|
}
|
||||||
|
return &out
|
||||||
|
},
|
||||||
"statusText": func(status string) string {
|
"statusText": func(status string) string {
|
||||||
switch status {
|
switch status {
|
||||||
case "pending", "restoring", "done", "failed", "skipped":
|
case "pending", "restoring", "done", "failed", "skipped":
|
||||||
|
|||||||
@@ -156,6 +156,15 @@ func TestLocaleFuncsHungarianBundleMatchesFuncMap(t *testing.T) {
|
|||||||
if got, want := b.Msg("hu", "func.time.yesterday"), timeAgo(now.Add(-30*time.Hour)); got != want {
|
if got, want := b.Msg("hu", "func.time.yesterday"), timeAgo(now.Add(-30*time.Hour)); got != want {
|
||||||
t.Errorf("yesterday: %q vs %q", got, want)
|
t.Errorf("yesterday: %q vs %q", got, want)
|
||||||
}
|
}
|
||||||
|
// infraMeta (slice 1): the Hungarian bundle carries the same curated words as inframeta.go.
|
||||||
|
for name, m := range infraMetaMap {
|
||||||
|
if got := b.Msg("hu", "func.infra."+name+".description"); got != m.Description {
|
||||||
|
t.Errorf("infra %s description: hu.json %q, inframeta.go %q", name, got, m.Description)
|
||||||
|
}
|
||||||
|
if k := "func.infra." + name + ".display"; b.Has("hu", k) && b.Msg("hu", k) != m.DisplayName {
|
||||||
|
t.Errorf("infra %s display: hu.json %q, inframeta.go %q", name, b.Msg("hu", k), m.DisplayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
// And the English funcs really are English.
|
// And the English funcs really are English.
|
||||||
en := s.localeFuncs("en")
|
en := s.localeFuncs("en")
|
||||||
if got := en["timeAgo"].(func(time.Time) string)(now.Add(-time.Minute - time.Second)); got != "1 minute ago" {
|
if got := en["timeAgo"].(func(time.Time) string)(now.Add(-time.Minute - time.Second)); got != "1 minute ago" {
|
||||||
@@ -238,3 +247,19 @@ func TestLanguageSwitch_EndToEnd(t *testing.T) {
|
|||||||
t.Error("back on Hungarian: the page must be Hungarian with no switch")
|
t.Error("back on Hungarian: the page must be Hungarian with no switch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// huTemplateSource returns an embedded template AS THE HUNGARIAN SET PARSES IT — markers expanded. Tests
|
||||||
|
// that assert on a template's Hungarian wording read this, never the raw file: since slice 1 the
|
||||||
|
// wording lives in hu.json, and a raw read would find a marker where the sentence used to be.
|
||||||
|
func huTemplateSource(name string) ([]byte, error) {
|
||||||
|
raw, err := templateFS.ReadFile(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b, err := i18n.Shared()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out, _ := b.Expand(i18n.Default, string(raw))
|
||||||
|
return []byte(out), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func TestNetworkStorageWarningsIn_UnreachableAloneUnchanged(t *testing.T) {
|
|||||||
// must never reuse the recoverable-unreachable copy; the unreachable line stays byte-identical).
|
// must never reuse the recoverable-unreachable copy; the unreachable line stays byte-identical).
|
||||||
func TestNetworkBadgeTemplates_DistinctStrings(t *testing.T) {
|
func TestNetworkBadgeTemplates_DistinctStrings(t *testing.T) {
|
||||||
for _, tpl := range []string{"templates/dashboard.html", "templates/stacks.html"} {
|
for _, tpl := range []string{"templates/dashboard.html", "templates/stacks.html"} {
|
||||||
body, err := os.ReadFile(tpl)
|
body, err := huTemplateSource(tpl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func TestSettingsSectionInventory(t *testing.T) {
|
|||||||
}
|
}
|
||||||
var union strings.Builder
|
var union strings.Builder
|
||||||
for _, f := range []string{"settings_system.html", "settings_notifications.html", "settings_security.html", "storage.html", "storage_network.html"} {
|
for _, f := range []string{"settings_system.html", "settings_notifications.html", "settings_security.html", "storage.html", "storage_network.html"} {
|
||||||
b, err := templateFS.ReadFile("templates/" + f)
|
b, err := huTemplateSource("templates/" + f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("read %s: %v", f, err)
|
t.Fatalf("read %s: %v", f, err)
|
||||||
}
|
}
|
||||||
@@ -224,7 +224,7 @@ func TestStorageNoNativeConfirm(t *testing.T) {
|
|||||||
// allow the pre-existing type-to-confirm overlay helper names
|
// allow the pre-existing type-to-confirm overlay helper names
|
||||||
allow := regexp.MustCompile(`openConfirm|__closeConfirm|confirmEject|confirmWipe|typeToConfirm|confirm-`)
|
allow := regexp.MustCompile(`openConfirm|__closeConfirm|confirmEject|confirmWipe|typeToConfirm|confirm-`)
|
||||||
for _, f := range []string{"storage.html", "storage_network.html", "settings_system.html", "settings_notifications.html", "settings_security.html"} {
|
for _, f := range []string{"storage.html", "storage_network.html", "settings_system.html", "settings_notifications.html", "settings_security.html"} {
|
||||||
b, err := templateFS.ReadFile("templates/" + f)
|
b, err := huTemplateSource("templates/" + f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("read %s: %v", f, err)
|
t.Fatalf("read %s: %v", f, err)
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ func TestStorageNoNativeConfirm(t *testing.T) {
|
|||||||
// TestStorageAgentDownNote (D1 Scenario C, static): the enrichment JS has an error path that
|
// TestStorageAgentDownNote (D1 Scenario C, static): the enrichment JS has an error path that
|
||||||
// renders the exact warn note into #agent-warn-note (graceful degradation when the agent is down).
|
// renders the exact warn note into #agent-warn-note (graceful degradation when the agent is down).
|
||||||
func TestStorageAgentDownNote(t *testing.T) {
|
func TestStorageAgentDownNote(t *testing.T) {
|
||||||
b, err := templateFS.ReadFile("templates/storage.html")
|
b, err := huTemplateSource("templates/storage.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -282,7 +282,7 @@ func TestNoEmojiInTemplates(t *testing.T) {
|
|||||||
if !strings.HasSuffix(e.Name(), ".html") {
|
if !strings.HasSuffix(e.Name(), ".html") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
b, err := templateFS.ReadFile("templates/" + e.Name())
|
b, err := huTemplateSource("templates/" + e.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ func TestStorageInit_PollsAgentFormatStatusOnTimeout(t *testing.T) {
|
|||||||
// /storage, not /settings. One assertion per template.
|
// /storage, not /settings. One assertion per template.
|
||||||
func TestStorageWizardBackAnchors_PointToStorage(t *testing.T) {
|
func TestStorageWizardBackAnchors_PointToStorage(t *testing.T) {
|
||||||
for _, file := range []string{"templates/storage_init.html", "templates/storage_attach.html"} {
|
for _, file := range []string{"templates/storage_init.html", "templates/storage_attach.html"} {
|
||||||
b, err := templateFS.ReadFile(file)
|
b, err := huTemplateSource(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("read %s: %v", file, err)
|
t.Fatalf("read %s: %v", file, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,15 @@
|
|||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<div style="display:flex;align-items:center;gap:1rem">
|
<div style="display:flex;align-items:center;gap:1rem">
|
||||||
<a href="/stacks" class="btn btn-sm btn-outline">← Alkalmazások</a>
|
<a href="/stacks" class="btn btn-sm btn-outline">{{T "app_export.alkalmazasok"}}</a>
|
||||||
<h2>{{.Stack.Meta.DisplayName}} — Exportálás</h2>
|
<h2>{{T "app_export.exportalas"}}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card" style="max-width:700px">
|
<div class="card" style="max-width:700px">
|
||||||
<h3>Mentés helye</h3>
|
<h3>{{T "app_export.mentes_helye"}}</h3>
|
||||||
<select id="destDrive" onchange="loadEstimate()" style="width:100%;padding:.5rem;margin-bottom:1rem">
|
<select id="destDrive" onchange="loadEstimate()" style="width:100%;padding:.5rem;margin-bottom:1rem">
|
||||||
<option value="">Válassz tárolót...</option>
|
<option value="">{{T "app_export.valassz_tarolot"}}</option>
|
||||||
{{range .Drives}}
|
{{range .Drives}}
|
||||||
<option value="{{.Path}}">{{if .Label}}{{.Label}} ({{.Path}}){{else}}{{.Path}}{{end}}</option>
|
<option value="{{.Path}}">{{if .Label}}{{.Label}} ({{.Path}}){{else}}{{.Path}}{{end}}</option>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -19,19 +19,19 @@
|
|||||||
|
|
||||||
<div id="estimateBox" style="display:none;background:var(--bg-2);border-radius:8px;padding:1rem;margin-bottom:1.5rem">
|
<div id="estimateBox" style="display:none;background:var(--bg-2);border-radius:8px;padding:1rem;margin-bottom:1.5rem">
|
||||||
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
||||||
<span>Konfiguráció:</span>
|
<span>{{T "app_export.konfiguracio"}}</span>
|
||||||
<span id="estConfig">-</span>
|
<span id="estConfig">-</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
||||||
<span>Felhasználói adatok:</span>
|
<span>{{T "app_export.felhasznaloi_adatok"}}</span>
|
||||||
<span id="estData">-</span>
|
<span id="estData">-</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;justify-content:space-between;font-weight:600;margin-bottom:.25rem;border-top:1px solid var(--line);padding-top:.5rem">
|
<div style="display:flex;justify-content:space-between;font-weight:600;margin-bottom:.25rem;border-top:1px solid var(--line);padding-top:.5rem">
|
||||||
<span>Összesen:</span>
|
<span>{{T "app_export.osszesen"}}</span>
|
||||||
<span><span id="estTotal">-</span> <span id="estFree" style="color:var(--text-3)">(szabad: -)</span></span>
|
<span><span id="estTotal">-</span> <span id="estFree" style="color:var(--text-3)">{{T "app_export.szabad"}}</span></span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;justify-content:space-between">
|
<div style="display:flex;justify-content:space-between">
|
||||||
<span>Becsült idő:</span>
|
<span>{{T "app_export.becsult_ido"}}</span>
|
||||||
<span id="estTime">-</span>
|
<span id="estTime">-</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="estWarning" style="display:none;color:var(--crit);margin-top:.5rem;font-weight:600"></div>
|
<div id="estWarning" style="display:none;color:var(--crit);margin-top:.5rem;font-weight:600"></div>
|
||||||
@@ -39,53 +39,53 @@
|
|||||||
|
|
||||||
<div id="classSelect" style="display:none;margin-bottom:1.5rem">
|
<div id="classSelect" style="display:none;margin-bottom:1.5rem">
|
||||||
<div id="mandBox" style="display:none;margin-bottom:1rem">
|
<div id="mandBox" style="display:none;margin-bottom:1rem">
|
||||||
<div style="font-weight:600;margin-bottom:.25rem">Mindig része a mentésnek:</div>
|
<div style="font-weight:600;margin-bottom:.25rem">{{T "app_export.mindig_resze_a_mentesnek"}}</div>
|
||||||
<div id="mandList" style="color:var(--text-3);font-size:.9rem"></div>
|
<div id="mandList" style="color:var(--text-3);font-size:.9rem"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="optBox" style="display:none;margin-bottom:1rem">
|
<div id="optBox" style="display:none;margin-bottom:1rem">
|
||||||
<div style="font-weight:600;margin-bottom:.25rem">Választható tartalom:</div>
|
<div style="font-weight:600;margin-bottom:.25rem">{{T "app_export.valaszthato_tartalom"}}</div>
|
||||||
<div id="optList"></div>
|
<div id="optList"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="exclBox" style="display:none">
|
<div id="exclBox" style="display:none">
|
||||||
<div id="exclSummary" style="margin-bottom:.25rem"></div>
|
<div id="exclSummary" style="margin-bottom:.25rem"></div>
|
||||||
<div style="color:var(--text-3);font-size:.85rem;margin-bottom:.5rem">A kihagyott mappák tartalma a Fájlkezelőben bármikor elérhető, és külön is lementhető.</div>
|
<div style="color:var(--text-3);font-size:.85rem;margin-bottom:.5rem">{{T "app_export.a_kihagyott_mappak_tartalma_a"}}</div>
|
||||||
<button type="button" class="btn btn-xs btn-outline" onclick="toggleExcl()" id="exclToggle">Kihagyott tartalom megjelenítése</button>
|
<button type="button" class="btn btn-xs btn-outline" onclick="toggleExcl()" id="exclToggle">{{T "app_export.kihagyott_tartalom_megjelenitese"}}</button>
|
||||||
<div id="exclList" style="display:none;margin-top:.5rem"></div>
|
<div id="exclList" style="display:none;margin-top:.5rem"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3>Jelszó (opcionális)</h3>
|
<h3>{{T "app_export.jelszo_opcionalis"}}</h3>
|
||||||
<div style="display:flex;gap:.5rem;margin-bottom:1rem">
|
<div style="display:flex;gap:.5rem;margin-bottom:1rem">
|
||||||
<input type="password" id="exportPassword" placeholder="Titkosítási jelszó" style="flex:1;padding:.5rem">
|
<input type="password" id="exportPassword" placeholder="{{T "app_export.titkositasi_jelszo"}}" style="flex:1;padding:.5rem">
|
||||||
<button class="btn btn-sm btn-outline" onclick="togglePw()" type="button" title="Jelszó mutatása">👁</button>
|
<button class="btn btn-sm btn-outline" onclick="togglePw()" type="button" title="{{T "app_export.jelszo_mutatasa"}}">👁</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label style="display:flex;align-items:flex-start;gap:.5rem;margin-bottom:.5rem;cursor:pointer">
|
<label style="display:flex;align-items:flex-start;gap:.5rem;margin-bottom:.5rem;cursor:pointer">
|
||||||
<input type="checkbox" id="stopApp" checked style="margin-top:3px">
|
<input type="checkbox" id="stopApp" checked style="margin-top:3px">
|
||||||
<div>
|
<div>
|
||||||
<strong>Alkalmazás leállítása mentés előtt (ajánlott)</strong>
|
<strong>{{T "app_export.alkalmazas_leallitasa_mentes_elott_ajanl"}}</strong>
|
||||||
<div style="color:var(--text-3);font-size:.85rem">Az adatok konzisztenciája érdekében javasolt leállítani az alkalmazást mentés közben.</div>
|
<div style="color:var(--text-3);font-size:.85rem">{{T "app_export.az_adatok_konzisztenciaja_erdekeben_java"}}</div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<button id="startBtn" class="btn btn-primary" onclick="startExport()" style="margin-top:1rem;width:100%" disabled>
|
<button id="startBtn" class="btn btn-primary" onclick="startExport()" style="margin-top:1rem;width:100%" disabled>
|
||||||
Exportálás indítása
|
{{T "app_export.exportalas_inditasa"}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="progressCard" class="card" style="max-width:700px;display:none">
|
<div id="progressCard" class="card" style="max-width:700px;display:none">
|
||||||
<h3>Folyamat</h3>
|
<h3>{{T "app_export.folyamat"}}</h3>
|
||||||
<div id="progressSteps"></div>
|
<div id="progressSteps"></div>
|
||||||
<div id="progressError" style="display:none;color:var(--crit);margin-top:1rem;font-weight:600"></div>
|
<div id="progressError" style="display:none;color:var(--crit);margin-top:1rem;font-weight:600"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="doneCard" class="card" style="max-width:700px;display:none">
|
<div id="doneCard" class="card" style="max-width:700px;display:none">
|
||||||
<h3 style="color:var(--blue)">Kész!</h3>
|
<h3 style="color:var(--blue)">{{T "app_export.kesz"}}</h3>
|
||||||
<div style="margin-bottom:1rem">
|
<div style="margin-bottom:1rem">
|
||||||
<span id="doneFile" style="font-weight:600"></span>
|
<span id="doneFile" style="font-weight:600"></span>
|
||||||
<span id="doneSize" style="color:var(--text-3)"></span>
|
<span id="doneSize" style="color:var(--text-3)"></span>
|
||||||
</div>
|
</div>
|
||||||
<a id="doneFBLink" href="#" target="_blank" class="btn btn-outline">Megnyitás FileBrowser-ben ↗</a>
|
<a id="doneFBLink" href="#" target="_blank" class="btn btn-outline">{{T "app_export.megnyitas_filebrowser_ben"}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -126,12 +126,12 @@ async function loadEstimate() {
|
|||||||
document.getElementById('estConfig').textContent = est.config_size_human;
|
document.getElementById('estConfig').textContent = est.config_size_human;
|
||||||
document.getElementById('estData').textContent = est.data_size_human;
|
document.getElementById('estData').textContent = est.data_size_human;
|
||||||
document.getElementById('estTotal').textContent = '~' + est.total_size_human;
|
document.getElementById('estTotal').textContent = '~' + est.total_size_human;
|
||||||
document.getElementById('estFree').textContent = '(szabad: ' + est.dest_free_human + ')';
|
document.getElementById('estFree').textContent = '{{T "app_export.szabad_2"}} ' + est.dest_free_human + ')';
|
||||||
document.getElementById('estTime').textContent = '~' + est.estimated_minutes + ' perc';
|
document.getElementById('estTime').textContent = '~' + est.estimated_minutes + ' {{T "app_export.perc"}}';
|
||||||
|
|
||||||
var warn = document.getElementById('estWarning');
|
var warn = document.getElementById('estWarning');
|
||||||
if (!est.fits_on_dest) {
|
if (!est.fits_on_dest) {
|
||||||
warn.textContent = 'Nincs elég szabad hely a kiválasztott tárolón!';
|
warn.textContent = '{{T "app_export.nincs_eleg_szabad_hely_a"}}';
|
||||||
warn.style.display = 'block';
|
warn.style.display = 'block';
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -200,14 +200,14 @@ function recomputeTotal() {
|
|||||||
var full = alap + exclAll;
|
var full = alap + exclAll;
|
||||||
var s = document.getElementById('exclSummary');
|
var s = document.getElementById('exclSummary');
|
||||||
if ((lastEst.excluded_items||[]).length) {
|
if ((lastEst.excluded_items||[]).length) {
|
||||||
s.innerHTML = 'Alap mentés: ~' + humanBytes(alap) + '. A kihagyott, nagy méretű tartalommal együtt: ~' + humanBytes(full) + '.';
|
s.innerHTML = '{{T "app_export.alap_mentes"}}' + humanBytes(alap) + '{{T "app_export.a_kihagyott_nagy_meretu_tartalommal"}}' + humanBytes(full) + '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function toggleExcl() {
|
function toggleExcl() {
|
||||||
var l = document.getElementById('exclList');
|
var l = document.getElementById('exclList');
|
||||||
var shown = l.style.display !== 'none';
|
var shown = l.style.display !== 'none';
|
||||||
l.style.display = shown ? 'none' : 'block';
|
l.style.display = shown ? 'none' : 'block';
|
||||||
document.getElementById('exclToggle').textContent = shown ? 'Kihagyott tartalom megjelenítése' : 'Kihagyott tartalom elrejtése';
|
document.getElementById('exclToggle').textContent = shown ? '{{T "app_export.kihagyott_tartalom_megjelenitese"}}' : '{{T "app_export.kihagyott_tartalom_elrejtese"}}';
|
||||||
}
|
}
|
||||||
function gatherSelections() {
|
function gatherSelections() {
|
||||||
var deselect = [], optIn = [];
|
var deselect = [], optIn = [];
|
||||||
@@ -242,7 +242,7 @@ async function startExport() {
|
|||||||
});
|
});
|
||||||
var data = await resp.json();
|
var data = await resp.json();
|
||||||
if (!data.ok) {
|
if (!data.ok) {
|
||||||
showError(data.error || 'Hiba történt');
|
showError(data.error || '{{T "common.hiba_tortent"}}');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pollStatus();
|
pollStatus();
|
||||||
|
|||||||
@@ -3,22 +3,22 @@
|
|||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<div style="display:flex;align-items:center;gap:1rem">
|
<div style="display:flex;align-items:center;gap:1rem">
|
||||||
<a href="/stacks" class="btn btn-sm btn-outline">← Alkalmazások</a>
|
<a href="/stacks" class="btn btn-sm btn-outline">{{T "app_import.alkalmazasok"}}</a>
|
||||||
<h2>Alkalmazás importálás</h2>
|
<h2>{{T "app_import.alkalmazas_importalas"}}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Browser .fab upload (v0.128.0) — chunked, because the Cloudflare tunnel caps request bodies (~100 MB) -->
|
<!-- Browser .fab upload (v0.128.0) — chunked, because the Cloudflare tunnel caps request bodies (~100 MB) -->
|
||||||
<div class="card" style="max-width:900px;margin-bottom:1rem">
|
<div class="card" style="max-width:900px;margin-bottom:1rem">
|
||||||
<div id="fabUploadZone" style="border:1px dashed var(--line);border-radius:var(--radius);padding:1.25rem;text-align:center;cursor:pointer" onclick="fabPick()">
|
<div id="fabUploadZone" style="border:1px dashed var(--line);border-radius:var(--radius);padding:1.25rem;text-align:center;cursor:pointer" onclick="fabPick()">
|
||||||
<p style="color:var(--text-2);margin:0 0 .75rem">.fab csomag feltöltése — húzza ide, vagy válassza ki a fájlt</p>
|
<p style="color:var(--text-2);margin:0 0 .75rem">{{T "app_import.fab_csomag_feltoltese_huzza_ide"}}</p>
|
||||||
<button type="button" class="btn btn-sm btn-outline">Fájl kiválasztása</button>
|
<button type="button" class="btn btn-sm btn-outline">{{T "app_import.fajl_kivalasztasa"}}</button>
|
||||||
<input type="file" id="fabFileInput" accept=".fab" style="display:none">
|
<input type="file" id="fabFileInput" accept=".fab" style="display:none">
|
||||||
</div>
|
</div>
|
||||||
<div id="fabUpProgress" style="display:none;margin-top:1rem">
|
<div id="fabUpProgress" style="display:none;margin-top:1rem">
|
||||||
<div style="display:flex;justify-content:space-between;align-items:center;gap:1rem">
|
<div style="display:flex;justify-content:space-between;align-items:center;gap:1rem">
|
||||||
<span id="fabUpText" style="color:var(--text-2)">Feltöltés: 0%</span>
|
<span id="fabUpText" style="color:var(--text-2)">{{T "app_import.feltoltes_0"}}</span>
|
||||||
<button type="button" class="btn btn-sm btn-outline" onclick="fabCancel()">Megszakítás</button>
|
<button type="button" class="btn btn-sm btn-outline" onclick="fabCancel()">{{T "app_import.megszakitas"}}</button>
|
||||||
</div>
|
</div>
|
||||||
<div style="background:var(--bg-2);border-radius:var(--radius);height:6px;margin-top:.5rem;overflow:hidden">
|
<div style="background:var(--bg-2);border-radius:var(--radius);height:6px;margin-top:.5rem;overflow:hidden">
|
||||||
<div id="fabUpBar" style="background:var(--blue);height:100%;width:0%"></div>
|
<div id="fabUpBar" style="background:var(--blue);height:100%;width:0%"></div>
|
||||||
@@ -29,19 +29,19 @@
|
|||||||
|
|
||||||
{{if not .Bundles}}
|
{{if not .Bundles}}
|
||||||
<div class="card" style="max-width:700px">
|
<div class="card" style="max-width:700px">
|
||||||
<p style="color:var(--text-3)">Nem található .fab csomag a regisztrált tárolókon.</p>
|
<p style="color:var(--text-3)">{{T "app_import.nem_talalhato_fab_csomag_a"}}</p>
|
||||||
<p style="color:var(--text-3);font-size:.85rem">Exportálj egy alkalmazást az alkalmazás oldaláról, tölts fel egy .fab fájlt itt fent, vagy másolj egyet a <code>{tároló}/felhom-data/exports/</code> könyvtárba.</p>
|
<p style="color:var(--text-3);font-size:.85rem">{{T "app_import.exportalj_egy_alkalmazast_az_alkalmazas"}}</p>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="card" style="max-width:900px">
|
<div class="card" style="max-width:900px">
|
||||||
<table class="table" style="width:100%">
|
<table class="table" style="width:100%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Alkalmazás</th>
|
<th>{{T "app_import.alkalmazas"}}</th>
|
||||||
<th>Dátum</th>
|
<th>{{T "app_import.datum"}}</th>
|
||||||
<th>Méret</th>
|
<th>{{T "app_import.meret"}}</th>
|
||||||
<th>Tároló</th>
|
<th>{{T "app_import.tarolo"}}</th>
|
||||||
<th>Titkos</th>
|
<th>{{T "app_import.titkos"}}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
<td>{{.SizeHuman}}</td>
|
<td>{{.SizeHuman}}</td>
|
||||||
<td>{{if .DriveLabel}}{{.DriveLabel}}{{else}}{{.DrivePath}}{{end}}</td>
|
<td>{{if .DriveLabel}}{{.DriveLabel}}{{else}}{{.DrivePath}}{{end}}</td>
|
||||||
<td>{{if .Encrypted}}🔒{{end}}</td>
|
<td>{{if .Encrypted}}🔒{{end}}</td>
|
||||||
<td><button class="btn btn-sm btn-outline" onclick="showPreview('{{.Path}}', {{.Encrypted}})">Részletek »</button></td>
|
<td><button class="btn btn-sm btn-outline" onclick="showPreview('{{.Path}}', {{.Encrypted}})">{{T "app_import.reszletek"}}</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -63,13 +63,13 @@
|
|||||||
|
|
||||||
<!-- Preview / password modal -->
|
<!-- Preview / password modal -->
|
||||||
<div id="previewCard" class="card" style="max-width:700px;display:none">
|
<div id="previewCard" class="card" style="max-width:700px;display:none">
|
||||||
<h3 id="previewTitle">Csomag részletei</h3>
|
<h3 id="previewTitle">{{T "app_import.csomag_reszletei"}}</h3>
|
||||||
|
|
||||||
<div id="passwordPrompt" style="display:none;margin-bottom:1rem">
|
<div id="passwordPrompt" style="display:none;margin-bottom:1rem">
|
||||||
<p>Ez a csomag jelszóval védett. Kérlek add meg a jelszót:</p>
|
<p>{{T "app_import.ez_a_csomag_jelszoval_vedett"}}</p>
|
||||||
<div style="display:flex;gap:.5rem">
|
<div style="display:flex;gap:.5rem">
|
||||||
<input type="password" id="importPassword" class="form-input" autocomplete="off" placeholder="Jelszó" style="flex:1">
|
<input type="password" id="importPassword" class="form-input" autocomplete="off" placeholder="{{T "common.jelszo"}}" style="flex:1">
|
||||||
<button class="btn btn-primary" onclick="loadManifest()">Megnyitás</button>
|
<button class="btn btn-primary" onclick="loadManifest()">{{T "app_import.megnyitas"}}</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="passwordError" style="display:none;color:var(--crit);margin-top:.5rem"></div>
|
<div id="passwordError" style="display:none;color:var(--crit);margin-top:.5rem"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -77,52 +77,52 @@
|
|||||||
<div id="manifestInfo" style="display:none">
|
<div id="manifestInfo" style="display:none">
|
||||||
<div style="background:var(--bg-2);border-radius:8px;padding:1rem;margin-bottom:1rem">
|
<div style="background:var(--bg-2);border-radius:8px;padding:1rem;margin-bottom:1rem">
|
||||||
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
||||||
<span>Alkalmazás:</span>
|
<span>{{T "app_import.alkalmazas_2"}}</span>
|
||||||
<strong id="mfName">-</strong>
|
<strong id="mfName">-</strong>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
||||||
<span>Exportálva:</span>
|
<span>{{T "app_import.exportalva"}}</span>
|
||||||
<span id="mfDate">-</span>
|
<span id="mfDate">-</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
||||||
<span>Controller verzió:</span>
|
<span>{{T "app_import.controller_verzio"}}</span>
|
||||||
<span id="mfVersion">-</span>
|
<span id="mfVersion">-</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="mfDBRow" style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
<div id="mfDBRow" style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
||||||
<span>Adatbázis:</span>
|
<span>{{T "app_import.adatbazis"}}</span>
|
||||||
<span id="mfDB">-</span>
|
<span id="mfDB">-</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
<div style="display:flex;justify-content:space-between;margin-bottom:.25rem">
|
||||||
<span>Adatok:</span>
|
<span>{{T "app_import.adatok"}}</span>
|
||||||
<span id="mfDataType">-</span>
|
<span id="mfDataType">-</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;justify-content:space-between">
|
<div style="display:flex;justify-content:space-between">
|
||||||
<span>Méret:</span>
|
<span>{{T "app_import.meret_2"}}</span>
|
||||||
<span id="mfSize">-</span>
|
<span id="mfSize">-</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="overwriteWarning" style="display:none;background:var(--warning-bg, #fff3cd);border:1px solid var(--warning-border, #ffc107);border-radius:8px;padding:1rem;margin-bottom:1rem">
|
<div id="overwriteWarning" style="display:none;background:var(--warning-bg, #fff3cd);border:1px solid var(--warning-border, #ffc107);border-radius:8px;padding:1rem;margin-bottom:1rem">
|
||||||
<strong>⚠ FIGYELEM:</strong> A meglévő <span id="overwriteAppName"></span> alkalmazás konfigurációja és összes adata felül lesz írva!
|
{{T "app_import.figyelem_a_meglevo"}} <span id="overwriteAppName"></span> {{T "app_import.alkalmazas_konfiguracioja_es_osszes_adat"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="importBtn" class="btn btn-primary" onclick="startImport()" style="width:100%">
|
<button id="importBtn" class="btn btn-primary" onclick="startImport()" style="width:100%">
|
||||||
Visszaállítás indítása
|
{{T "app_import.visszaallitas_inditasa"}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Progress -->
|
<!-- Progress -->
|
||||||
<div id="progressCard" class="card" style="max-width:700px;display:none">
|
<div id="progressCard" class="card" style="max-width:700px;display:none">
|
||||||
<h3>Importálás folyamata</h3>
|
<h3>{{T "app_import.importalas_folyamata"}}</h3>
|
||||||
<div id="progressSteps"></div>
|
<div id="progressSteps"></div>
|
||||||
<div id="progressError" style="display:none;color:var(--crit);margin-top:1rem;font-weight:600"></div>
|
<div id="progressError" style="display:none;color:var(--crit);margin-top:1rem;font-weight:600"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="doneCard" class="card" style="max-width:700px;display:none">
|
<div id="doneCard" class="card" style="max-width:700px;display:none">
|
||||||
<h3 style="color:var(--blue)">Importálás kész!</h3>
|
<h3 style="color:var(--blue)">{{T "app_import.importalas_kesz"}}</h3>
|
||||||
<p>Az alkalmazás sikeresen visszaállítva.</p>
|
<p>{{T "app_import.az_alkalmazas_sikeresen_visszaallitva"}}</p>
|
||||||
<a id="doneLink" href="/stacks" class="btn btn-primary">Alkalmazások megtekintése</a>
|
<a id="doneLink" href="/stacks" class="btn btn-primary">{{T "app_import.alkalmazasok_megtekintese"}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -170,7 +170,7 @@ async function loadManifest() {
|
|||||||
|
|
||||||
if (!data.ok) {
|
if (!data.ok) {
|
||||||
if (selectedEncrypted) {
|
if (selectedEncrypted) {
|
||||||
document.getElementById('passwordError').textContent = data.error || 'Hibás jelszó';
|
document.getElementById('passwordError').textContent = data.error || '{{T "app_import.hibas_jelszo"}}';
|
||||||
document.getElementById('passwordError').style.display = 'block';
|
document.getElementById('passwordError').style.display = 'block';
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -193,7 +193,7 @@ function showManifest(m) {
|
|||||||
document.getElementById('passwordPrompt').style.display = 'none';
|
document.getElementById('passwordPrompt').style.display = 'none';
|
||||||
document.getElementById('manifestInfo').style.display = 'block';
|
document.getElementById('manifestInfo').style.display = 'block';
|
||||||
|
|
||||||
document.getElementById('previewTitle').textContent = (m.display_name || m.app_name) + ' — Csomag részletei';
|
document.getElementById('previewTitle').textContent = (m.display_name || m.app_name) + ' {{T "app_import.csomag_reszletei_2"}}';
|
||||||
document.getElementById('mfName').textContent = m.display_name || m.app_name;
|
document.getElementById('mfName').textContent = m.display_name || m.app_name;
|
||||||
document.getElementById('mfDate').textContent = m.exported_at ? new Date(m.exported_at).toLocaleString('hu-HU') : '-';
|
document.getElementById('mfDate').textContent = m.exported_at ? new Date(m.exported_at).toLocaleString('hu-HU') : '-';
|
||||||
document.getElementById('mfVersion').textContent = m.controller_version || '-';
|
document.getElementById('mfVersion').textContent = m.controller_version || '-';
|
||||||
@@ -208,7 +208,7 @@ function showManifest(m) {
|
|||||||
var dataType = [];
|
var dataType = [];
|
||||||
if (m.has_hdd_data) dataType.push('HDD');
|
if (m.has_hdd_data) dataType.push('HDD');
|
||||||
if (m.has_volume_data) dataType.push('Docker volume');
|
if (m.has_volume_data) dataType.push('Docker volume');
|
||||||
document.getElementById('mfDataType').textContent = dataType.length ? dataType.join(', ') : 'Nincs';
|
document.getElementById('mfDataType').textContent = dataType.length ? dataType.join(', ') : '{{T "app_import.nincs"}}';
|
||||||
|
|
||||||
// Format size
|
// Format size
|
||||||
var bytes = m.total_size_bytes || 0;
|
var bytes = m.total_size_bytes || 0;
|
||||||
@@ -240,7 +240,7 @@ async function startImport() {
|
|||||||
});
|
});
|
||||||
var data = await resp.json();
|
var data = await resp.json();
|
||||||
if (!data.ok) {
|
if (!data.ok) {
|
||||||
showError(data.error || 'Hiba történt');
|
showError(data.error || '{{T "common.hiba_tortent"}}');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pollStatus();
|
pollStatus();
|
||||||
@@ -269,7 +269,7 @@ function pollStatus() {
|
|||||||
document.getElementById('doneCard').style.display = 'block';
|
document.getElementById('doneCard').style.display = 'block';
|
||||||
if (data.stack_name) {
|
if (data.stack_name) {
|
||||||
document.getElementById('doneLink').href = '/stacks/' + data.stack_name + '/deploy';
|
document.getElementById('doneLink').href = '/stacks/' + data.stack_name + '/deploy';
|
||||||
document.getElementById('doneLink').textContent = 'Alkalmazás megtekintése';
|
document.getElementById('doneLink').textContent = '{{T "app_import.alkalmazas_megtekintese"}}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@@ -305,7 +305,7 @@ function showError(msg) {
|
|||||||
// network error, re-syncing from the server's 409 received_bytes echo; progress from bytes acked.
|
// network error, re-syncing from the server's 409 received_bytes echo; progress from bytes acked.
|
||||||
var fabUploadId = null;
|
var fabUploadId = null;
|
||||||
var fabCancelled = false;
|
var fabCancelled = false;
|
||||||
var fabNetErrText = 'A feltöltés megszakadt — ellenőrizze a kapcsolatot, majd próbálja újra.';
|
var fabNetErrText = '{{T "app_import.a_feltoltes_megszakadt_ellenorizze_a"}}';
|
||||||
|
|
||||||
function csrfRawH() {
|
function csrfRawH() {
|
||||||
var el = document.querySelector('meta[name="csrf-token"]');
|
var el = document.querySelector('meta[name="csrf-token"]');
|
||||||
@@ -323,7 +323,7 @@ function fabGB(b) {
|
|||||||
function fabProgress(done, total) {
|
function fabProgress(done, total) {
|
||||||
var pct = total > 0 ? Math.floor(done * 100 / total) : 0;
|
var pct = total > 0 ? Math.floor(done * 100 / total) : 0;
|
||||||
document.getElementById('fabUpText').textContent =
|
document.getElementById('fabUpText').textContent =
|
||||||
'Feltöltés: ' + pct + '% (' + fabGB(done) + ' / ' + fabGB(total) + ' GB)';
|
'{{T "app_import.feltoltes"}} ' + pct + '% (' + fabGB(done) + ' / ' + fabGB(total) + ' GB)';
|
||||||
document.getElementById('fabUpBar').style.width = pct + '%';
|
document.getElementById('fabUpBar').style.width = pct + '%';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +355,7 @@ async function fabStart(file) {
|
|||||||
if (!file) return;
|
if (!file) return;
|
||||||
document.getElementById('fabUpError').style.display = 'none';
|
document.getElementById('fabUpError').style.display = 'none';
|
||||||
if (!file.name.toLowerCase().endsWith('.fab')) {
|
if (!file.name.toLowerCase().endsWith('.fab')) {
|
||||||
fabFail('Csak .fab fájl tölthető fel.');
|
fabFail('{{T "app_import.csak_fab_fajl_toltheto_fel"}}');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fabCancelled = false;
|
fabCancelled = false;
|
||||||
@@ -410,7 +410,7 @@ async function fabStart(file) {
|
|||||||
var fd = await fin.json();
|
var fd = await fin.json();
|
||||||
if (!fd.ok) { fabFail(fd.error || fabNetErrText); return; }
|
if (!fd.ok) { fabFail(fd.error || fabNetErrText); return; }
|
||||||
fabUploadId = null;
|
fabUploadId = null;
|
||||||
document.getElementById('fabUpText').textContent = 'Feltöltés kész: ' + fd.filename;
|
document.getElementById('fabUpText').textContent = '{{T "app_import.feltoltes_kesz"}} ' + fd.filename;
|
||||||
document.getElementById('fabUpBar').style.width = '100%';
|
document.getElementById('fabUpBar').style.width = '100%';
|
||||||
// Refresh the bundle list through the EXISTING scan (the page render runs it).
|
// Refresh the bundle list through the EXISTING scan (the page render runs it).
|
||||||
setTimeout(function(){ window.location.reload(); }, 800);
|
setTimeout(function(){ window.location.reload(); }, 800);
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
<div style="display:flex;align-items:center;gap:.5rem">
|
<div style="display:flex;align-items:center;gap:.5rem">
|
||||||
{{if .Stack.Deployed}}
|
{{if .Stack.Deployed}}
|
||||||
<span class="stack-state-badge state-{{stateColor .Stack.State}}">{{stateLabel .Stack.State}}</span>
|
<span class="stack-state-badge state-{{stateColor .Stack.State}}">{{stateLabel .Stack.State}}</span>
|
||||||
{{if .Stack.Orphaned}}<span class="badge badge-orphaned">{{T "app_info.elavult"}}</span>{{end}}
|
{{if .Stack.Orphaned}}<span class="badge badge-orphaned">{{T "common.elavult"}}</span>{{end}}
|
||||||
{{template "meta_badge" (lifecycleBadge .Meta)}}
|
{{template "meta_badge" (lifecycleBadge .Meta)}}
|
||||||
{{template "meta_badge" (updateBadge .Stack)}}
|
{{template "meta_badge" (updateBadge .Stack)}}
|
||||||
{{if .EffectiveSubdomain}}<a href="https://{{.EffectiveSubdomain}}.{{.Domain}}{{.Meta.OpenPath}}" target="_blank" class="btn btn-sm btn-outline">{{T "app_info.megnyitas"}}</a>{{end}}
|
{{if .EffectiveSubdomain}}<a href="https://{{.EffectiveSubdomain}}.{{.Domain}}{{.Meta.OpenPath}}" target="_blank" class="btn btn-sm btn-outline">{{T "app_info.megnyitas"}}</a>{{end}}
|
||||||
<a href="/stacks/{{.Stack.Name}}/logs" class="btn btn-sm btn-outline">{{T "app_info.naplo"}}</a>
|
<a href="/stacks/{{.Stack.Name}}/logs" class="btn btn-sm btn-outline">{{T "app_info.naplo"}}</a>
|
||||||
{{if .Stack.Orphaned}}
|
{{if .Stack.Orphaned}}
|
||||||
<button class="btn btn-sm btn-danger" onclick="deleteOrphanStack('{{.Stack.Name}}')">{{T "app_info.torles"}}</button>
|
<button class="btn btn-sm btn-danger" onclick="deleteOrphanStack('{{.Stack.Name}}')">{{T "common.torles"}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a href="/stacks/{{.Stack.Name}}/export" class="btn btn-sm btn-outline">{{T "app_info.exportalas"}}</a>
|
<a href="/stacks/{{.Stack.Name}}/export" class="btn btn-sm btn-outline">{{T "app_info.exportalas"}}</a>
|
||||||
<a href="/stacks/{{.Stack.Name}}/deploy" class="btn btn-sm btn-outline">{{T "app_info.beallitasok"}}</a>
|
<a href="/stacks/{{.Stack.Name}}/deploy" class="btn btn-sm btn-outline">{{T "app_info.beallitasok"}}</a>
|
||||||
@@ -57,9 +57,9 @@
|
|||||||
<div class="stack-meta-badges">
|
<div class="stack-meta-badges">
|
||||||
<span class="meta-badge">~{{.Meta.Resources.MemRequest}} RAM</span>
|
<span class="meta-badge">~{{.Meta.Resources.MemRequest}} RAM</span>
|
||||||
<span class="meta-badge">{{.Meta.Category}}</span>
|
<span class="meta-badge">{{.Meta.Category}}</span>
|
||||||
{{if .Meta.Resources.NeedsHDD}}<span class="meta-badge meta-badge-warn">{{T "app_info.hdd_szukseges"}}</span>{{end}}
|
{{if .Meta.Resources.NeedsHDD}}<span class="meta-badge meta-badge-warn">{{T "common.hdd_szukseges"}}</span>{{end}}
|
||||||
{{if .Meta.Resources.PiCompatible}}<span class="meta-badge meta-badge-ok">{{T "app_info.pi_kompatibilis"}}</span>{{else}}<span class="meta-badge meta-badge-warn">{{T "app_info.csak_x86"}}</span>{{end}}
|
{{if .Meta.Resources.PiCompatible}}<span class="meta-badge meta-badge-ok">{{T "common.pi_kompatibilis"}}</span>{{else}}<span class="meta-badge meta-badge-warn">{{T "app_info.csak_x86"}}</span>{{end}}
|
||||||
{{if .Meta.Resources.HungarianUI}}<span class="meta-badge meta-badge-ok">{{T "app_info.magyar_felulet"}}</span>{{end}}
|
{{if .Meta.Resources.HungarianUI}}<span class="meta-badge meta-badge-ok">{{T "common.magyar_felulet"}}</span>{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{if .Meta.IsAbandoned}}
|
{{if .Meta.IsAbandoned}}
|
||||||
<div class="alert alert-warning" style="margin-top:.75rem">
|
<div class="alert alert-warning" style="margin-top:.75rem">
|
||||||
@@ -139,8 +139,8 @@ function appMigrate(btn,app,label){
|
|||||||
if(!target){ showAlert('{{T "app_info.valassz_celtarhelyet_2"}}'); return; }
|
if(!target){ showAlert('{{T "app_info.valassz_celtarhelyet_2"}}'); return; }
|
||||||
felhomConfirm(btn,'{{T "app_info.athelyezed_a_z"}} '+label+' {{T "app_info.adatait_ide"}} '+target+'{{T "app_info.az_alkalmazas_rovid_idore_leall"}}',function(){
|
felhomConfirm(btn,'{{T "app_info.athelyezed_a_z"}} '+label+' {{T "app_info.adatait_ide"}} '+target+'{{T "app_info.az_alkalmazas_rovid_idore_leall"}}',function(){
|
||||||
fetch('/api/storage/migrate-app',{method:'POST',headers:Object.assign({'Content-Type':'application/json'},csrfHeaders()),body:JSON.stringify({app:app,target:target})})
|
fetch('/api/storage/migrate-app',{method:'POST',headers:Object.assign({'Content-Type':'application/json'},csrfHeaders()),body:JSON.stringify({app:app,target:target})})
|
||||||
.then(function(r){return r.json();}).then(function(d){ if(d.ok){ appMigWatch(); } else { showAlert('{{T "app_info.hiba"}} '+(d.error||'{{T "app_info.ismeretlen"}}')); } })
|
.then(function(r){return r.json();}).then(function(d){ if(d.ok){ appMigWatch(); } else { showAlert('{{T "common.hiba_kettospont"}} '+(d.error||'{{T "app_info.ismeretlen"}}')); } })
|
||||||
.catch(function(e){ showAlert('{{T "app_info.hiba"}} '+e); });
|
.catch(function(e){ showAlert('{{T "common.hiba_kettospont"}} '+e); });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
(function(){ fetch('/api/storage/migrate/status').then(function(r){return r.json();}).then(function(d){ if(d.data&&d.data.job){ appMigWatch(); } }).catch(function(){}); })();
|
(function(){ fetch('/api/storage/migrate/status').then(function(r){return r.json();}).then(function(d){ if(d.data&&d.data.job){ appMigWatch(); } }).catch(function(){}); })();
|
||||||
@@ -188,12 +188,12 @@ function appMigrate(btn,app,label){
|
|||||||
{{end}}
|
{{end}}
|
||||||
{{if .InitialCredsOperatorSet}}
|
{{if .InitialCredsOperatorSet}}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="initcred-label" style="padding:.25rem .75rem .25rem 0;color:var(--text-3);white-space:nowrap">{{T "app_info.jelszo"}}</td>
|
<td class="initcred-label" style="padding:.25rem .75rem .25rem 0;color:var(--text-3);white-space:nowrap">{{T "common.jelszo"}}</td>
|
||||||
<td>{{T "app_info.az_uzemelteto_allitotta_be"}}</td>
|
<td>{{T "app_info.az_uzemelteto_allitotta_be"}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{else}}
|
{{else}}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="initcred-label" style="padding:.25rem .75rem .25rem 0;color:var(--text-3);white-space:nowrap;vertical-align:middle">{{T "app_info.jelszo"}}</td>
|
<td class="initcred-label" style="padding:.25rem .75rem .25rem 0;color:var(--text-3);white-space:nowrap;vertical-align:middle">{{T "common.jelszo"}}</td>
|
||||||
<!-- R-254: the value is NOT in this page. It used to be rendered into a `hidden`
|
<!-- R-254: the value is NOT in this page. It used to be rendered into a `hidden`
|
||||||
span, which stops a browser drawing it and nothing else — a fetch of this page
|
span, which stops a browser drawing it and nothing else — a fetch of this page
|
||||||
returned a real per-install password. Both buttons now ask the server. -->
|
returned a real per-install password. Both buttons now ask the server. -->
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
{{with $.SystemInfo}}
|
{{with $.SystemInfo}}
|
||||||
<div class="storage-item meter {{usageColor .DiskPercent}}">
|
<div class="storage-item meter {{usageColor .DiskPercent}}">
|
||||||
<div class="storage-header">
|
<div class="storage-header">
|
||||||
<span class="storage-label">{{T "backups.rendszer"}}</span>
|
<span class="storage-label">{{T "common.rendszer_gyoker"}}</span>
|
||||||
<span class="storage-value">{{fmtGB .DiskUsedGB}} / {{fmtGB .DiskTotalGB}} ({{printf "%.0f" .DiskPercent}}%)</span>
|
<span class="storage-value">{{fmtGB .DiskUsedGB}} / {{fmtGB .DiskTotalGB}} ({{printf "%.0f" .DiskPercent}}%)</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="meter-track">
|
<div class="meter-track">
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<div class="storage-item meter meter-empty storage-disconnected">
|
<div class="storage-item meter meter-empty storage-disconnected">
|
||||||
<div class="storage-header">
|
<div class="storage-header">
|
||||||
<span class="storage-label">{{.Label}}</span>
|
<span class="storage-label">{{.Label}}</span>
|
||||||
<span class="storage-value">— <span class="state-text-neutral">{{T "backups.levalasztva"}}</span></span>
|
<span class="storage-value">— <span class="state-text-neutral">{{T "common.levalasztva"}}</span></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="meter-track"></div>
|
<div class="meter-track"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -227,11 +227,11 @@ function triggerGuestBackup() {
|
|||||||
fetch('/api/guest-backup/trigger', { method: 'POST', headers: Object.assign({'Content-Type':'application/json'}, csrfHeaders()) })
|
fetch('/api/guest-backup/trigger', { method: 'POST', headers: Object.assign({'Content-Type':'application/json'}, csrfHeaders()) })
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (!data.ok) { out.innerHTML = '<div class="alert alert-error">' + (data.error || '{{T "backups.hiba"}}') + '</div>'; btn.disabled = false; return; }
|
if (!data.ok) { out.innerHTML = '<div class="alert alert-error">' + (data.error || '{{T "common.hiba"}}') + '</div>'; btn.disabled = false; return; }
|
||||||
out.innerHTML = '<span class="form-hint">{{T "backups.mentes_folyamatban"}}</span>';
|
out.innerHTML = '<span class="form-hint">{{T "backups.mentes_folyamatban"}}</span>';
|
||||||
pollGuestBackup(out, btn);
|
pollGuestBackup(out, btn);
|
||||||
})
|
})
|
||||||
.catch(e => { out.innerHTML = '<div class="alert alert-error">{{T "backups.hiba_2"}} ' + e + '</div>'; btn.disabled = false; });
|
.catch(e => { out.innerHTML = '<div class="alert alert-error">{{T "common.hiba_kettospont"}} ' + e + '</div>'; btn.disabled = false; });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +285,7 @@ function pollGuestBackup(out, btn) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function (e) {
|
.catch(function (e) {
|
||||||
out.innerHTML = '<div class="alert alert-error">{{T "backups.hiba_2"}} ' + e.message + '</div>';
|
out.innerHTML = '<div class="alert alert-error">{{T "common.hiba_kettospont"}} ' + e.message + '</div>';
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,22 +2,22 @@
|
|||||||
{{template "layout_start" .}}
|
{{template "layout_start" .}}
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>Vezérlőpult</h2>
|
<h2>{{T "dashboard.vezerlopult"}}</h2>
|
||||||
<span class="domain-badge">{{.Domain}}</span>
|
<span class="domain-badge">{{.Domain}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stats-grid">
|
<div class="stats-grid">
|
||||||
<a href="/stacks?filter=running" class="stat-card">
|
<a href="/stacks?filter=running" class="stat-card">
|
||||||
<div class="stat-value">{{.RunningCount}}</div>
|
<div class="stat-value">{{.RunningCount}}</div>
|
||||||
<div class="stat-label">Futó alkalmazás</div>
|
<div class="stat-label">{{T "dashboard.futo_alkalmazas"}}</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="/stacks?filter=stopped" class="stat-card {{if gt .StoppedCount 0}}stat-warn{{else}}stat-zero{{end}}">
|
<a href="/stacks?filter=stopped" class="stat-card {{if gt .StoppedCount 0}}stat-warn{{else}}stat-zero{{end}}">
|
||||||
<div class="stat-value">{{.StoppedCount}}</div>
|
<div class="stat-value">{{.StoppedCount}}</div>
|
||||||
<div class="stat-label">Leállítva</div>
|
<div class="stat-label">{{T "dashboard.leallitva"}}</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="/stacks" class="stat-card">
|
<a href="/stacks" class="stat-card">
|
||||||
<div class="stat-value">{{.TotalCount}}</div>
|
<div class="stat-value">{{.TotalCount}}</div>
|
||||||
<div class="stat-label">Összes alkalmazás</div>
|
<div class="stat-label">{{T "dashboard.osszes_alkalmazas"}}</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<div class="system-info-items">
|
<div class="system-info-items">
|
||||||
<div class="system-info-item meter {{usageColor .SystemInfo.MemPercent}}">
|
<div class="system-info-item meter {{usageColor .SystemInfo.MemPercent}}">
|
||||||
<div class="system-info-header">
|
<div class="system-info-header">
|
||||||
<span class="system-info-label">Memória</span>
|
<span class="system-info-label">{{T "dashboard.memoria"}}</span>
|
||||||
<span class="system-info-value">{{fmtMB .SystemInfo.UsedMemMB}} / {{fmtMB .SystemInfo.TotalMemMB}} ({{printf "%.0f" .SystemInfo.MemPercent}}%)</span>
|
<span class="system-info-value">{{fmtMB .SystemInfo.UsedMemMB}} / {{fmtMB .SystemInfo.TotalMemMB}} ({{printf "%.0f" .SystemInfo.MemPercent}}%)</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="meter-track">
|
<div class="meter-track">
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
{{if .SystemInfo.TemperatureCelsius}}
|
{{if .SystemInfo.TemperatureCelsius}}
|
||||||
<div class="system-info-item system-info-item-compact">
|
<div class="system-info-item system-info-item-compact">
|
||||||
<div class="system-info-header">
|
<div class="system-info-header">
|
||||||
<span class="system-info-label"><svg class="ico ico-sm"><use href="#i-thermometer"/></svg> Hőmérséklet</span>
|
<span class="system-info-label"><svg class="ico ico-sm"><use href="#i-thermometer"/></svg> {{T "dashboard.homerseklet"}}</span>
|
||||||
<span class="system-info-value temp-value state-text-{{tempColor .SystemInfo.TemperatureCelsius}}">{{fmtTemp .SystemInfo.TemperatureCelsius}}</span>
|
<span class="system-info-value temp-value state-text-{{tempColor .SystemInfo.TemperatureCelsius}}">{{fmtTemp .SystemInfo.TemperatureCelsius}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -61,23 +61,23 @@
|
|||||||
{{if not .SystemInfo.DiskKnown}}
|
{{if not .SystemInfo.DiskKnown}}
|
||||||
<div class="system-info-item meter meter-empty">
|
<div class="system-info-item meter meter-empty">
|
||||||
<div class="system-info-header">
|
<div class="system-info-header">
|
||||||
<span class="system-info-label">Rendszer (/)</span>
|
<span class="system-info-label">{{T "common.rendszer_gyoker"}}</span>
|
||||||
<span class="system-info-value">— <span class="state-text-neutral">nem ismert</span></span>
|
<span class="system-info-value">— <span class="state-text-neutral">{{T "dashboard.nem_ismert"}}</span></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="meter-track"></div>
|
<div class="meter-track"></div>
|
||||||
<div class="meter-flag">A tárhely mérete most nem olvasható ki.</div>
|
<div class="meter-flag">{{T "dashboard.a_tarhely_merete_most_nem"}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{$duc := usageColor .SystemInfo.DiskPercent}}
|
{{$duc := usageColor .SystemInfo.DiskPercent}}
|
||||||
<div class="system-info-item meter {{$duc}}">
|
<div class="system-info-item meter {{$duc}}">
|
||||||
<div class="system-info-header">
|
<div class="system-info-header">
|
||||||
<span class="system-info-label">Rendszer (/)</span>
|
<span class="system-info-label">{{T "common.rendszer_gyoker"}}</span>
|
||||||
<span class="system-info-value">{{fmtGB .SystemInfo.DiskUsedGB}} / {{fmtGB .SystemInfo.DiskTotalGB}} ({{printf "%.0f" .SystemInfo.DiskPercent}}%)</span>
|
<span class="system-info-value">{{fmtGB .SystemInfo.DiskUsedGB}} / {{fmtGB .SystemInfo.DiskTotalGB}} ({{printf "%.0f" .SystemInfo.DiskPercent}}%)</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="meter-track">
|
<div class="meter-track">
|
||||||
<div class="meter-fill" style="width:{{printf "%.0f" .SystemInfo.DiskPercent}}%"></div>
|
<div class="meter-fill" style="width:{{printf "%.0f" .SystemInfo.DiskPercent}}%"></div>
|
||||||
</div>
|
</div>
|
||||||
{{if eq $duc "warn"}}<div class="meter-flag"><svg class="ico"><use href="#i-triangle-alert"/></svg>Fogyóban a hely</div>{{else if eq $duc "crit"}}<div class="meter-flag"><svg class="ico"><use href="#i-triangle-alert"/></svg>Kritikusan kevés hely</div>{{end}}
|
{{if eq $duc "warn"}}<div class="meter-flag"><svg class="ico"><use href="#i-triangle-alert"/></svg>{{T "dashboard.fogyoban_a_hely"}}</div>{{else if eq $duc "crit"}}<div class="meter-flag"><svg class="ico"><use href="#i-triangle-alert"/></svg>{{T "dashboard.kritikusan_keves_hely"}}</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{range .StorageBars}}
|
{{range .StorageBars}}
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
<div class="system-info-item meter meter-empty storage-disconnected">
|
<div class="system-info-item meter meter-empty storage-disconnected">
|
||||||
<div class="system-info-header">
|
<div class="system-info-header">
|
||||||
<span class="system-info-label">{{.Label}}</span>
|
<span class="system-info-label">{{.Label}}</span>
|
||||||
<span class="system-info-value">— <span class="state-text-neutral">Leválasztva</span></span>
|
<span class="system-info-value">— <span class="state-text-neutral">{{T "common.levalasztva"}}</span></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="meter-track"></div>
|
<div class="meter-track"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
<div class="meter-track">
|
<div class="meter-track">
|
||||||
<div class="meter-fill" style="width:{{printf "%.0f" .Percent}}%"></div>
|
<div class="meter-fill" style="width:{{printf "%.0f" .Percent}}%"></div>
|
||||||
</div>
|
</div>
|
||||||
{{if eq $uc "warn"}}<div class="meter-flag"><svg class="ico"><use href="#i-triangle-alert"/></svg>Fogyóban a hely</div>{{else if eq $uc "crit"}}<div class="meter-flag"><svg class="ico"><use href="#i-triangle-alert"/></svg>Kritikusan kevés hely</div>{{end}}
|
{{if eq $uc "warn"}}<div class="meter-flag"><svg class="ico"><use href="#i-triangle-alert"/></svg>{{T "dashboard.fogyoban_a_hely"}}</div>{{else if eq $uc "crit"}}<div class="meter-flag"><svg class="ico"><use href="#i-triangle-alert"/></svg>{{T "dashboard.kritikusan_keves_hely"}}</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<div class="disk-health-card">
|
<div class="disk-health-card">
|
||||||
<h3>Lemezek állapota</h3>
|
<h3>{{T "dashboard.lemezek_allapota"}}</h3>
|
||||||
{{if .DiskHealthRows}}
|
{{if .DiskHealthRows}}
|
||||||
<ul class="disk-health-list">
|
<ul class="disk-health-list">
|
||||||
{{range .DiskHealthRows}}
|
{{range .DiskHealthRows}}
|
||||||
@@ -139,34 +139,34 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
{{else}}
|
{{else}}
|
||||||
<p class="form-hint state-text-neutral">Nincs adat</p>
|
<p class="form-hint state-text-neutral">{{T "dashboard.nincs_adat"}}</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if .BackupEnabled}}
|
{{if .BackupEnabled}}
|
||||||
<div class="backup-status-card">
|
<div class="backup-status-card">
|
||||||
<h3><a href="/backups" class="backup-card-link">Biztonsági mentés</a></h3>
|
<h3><a href="/backups" class="backup-card-link">{{T "dashboard.biztonsagi_mentes"}}</a></h3>
|
||||||
{{if .BackupStatus}}
|
{{if .BackupStatus}}
|
||||||
<div class="backup-info-row">
|
<div class="backup-info-row">
|
||||||
<span class="backup-label">Utolsó mentés:</span>
|
<span class="backup-label">{{T "dashboard.utolso_mentes"}}</span>
|
||||||
<span class="backup-value">
|
<span class="backup-value">
|
||||||
{{if .BackupStatus.Success}}
|
{{if .BackupStatus.Success}}
|
||||||
<span>{{.BackupStatus.LastRun.Format "2006-01-02 15:04"}}</span>
|
<span>{{.BackupStatus.LastRun.Format "2006-01-02 15:04"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class="backup-status-fail">Sikertelen</span>
|
<span class="backup-status-fail">{{T "dashboard.sikertelen"}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="backup-info-row">
|
<div class="backup-info-row">
|
||||||
<span class="backup-label">Utolsó mentés:</span>
|
<span class="backup-label">{{T "dashboard.utolso_mentes"}}</span>
|
||||||
<span class="backup-value backup-status-none">Még nem futott</span>
|
<span class="backup-value backup-status-none">{{T "dashboard.meg_nem_futott"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .DBDumpStatus}}
|
{{if .DBDumpStatus}}
|
||||||
<div class="backup-info-row">
|
<div class="backup-info-row">
|
||||||
<span class="backup-label">Adatbázisok:</span>
|
<span class="backup-label">{{T "dashboard.adatbazisok"}}</span>
|
||||||
<span class="backup-value">{{len .DBDumpStatus.Results}} mentve</span>
|
<span class="backup-value">{{T "dashboard.mentve"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{/* Cross-drive ("2. mentés") moved to the host agent in slice 8C — the dashboard handler no
|
{{/* Cross-drive ("2. mentés") moved to the host agent in slice 8C — the dashboard handler no
|
||||||
@@ -175,7 +175,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<h3>Telepített alkalmazások</h3>
|
<h3>{{T "dashboard.telepitett_alkalmazasok"}}</h3>
|
||||||
|
|
||||||
<div class="stack-list">
|
<div class="stack-list">
|
||||||
{{range .Stacks}}
|
{{range .Stacks}}
|
||||||
@@ -186,44 +186,44 @@
|
|||||||
{{template "app_list_row" dict "Slug" .Meta.Slug "Name" .Meta.DisplayName "Secondary" .Meta.Description "RowClass" (printf "stack-state-%s" (stateColor .State)) "Href" (appHref .Meta.Slug)}}
|
{{template "app_list_row" dict "Slug" .Meta.Slug "Name" .Meta.DisplayName "Secondary" .Meta.Description "RowClass" (printf "stack-state-%s" (stateColor .State)) "Href" (appHref .Meta.Slug)}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<span class="tag tag-{{stateColor .State}}"><span class="dot"></span>{{stateLabel .State}}</span>
|
<span class="tag tag-{{stateColor .State}}"><span class="dot"></span>{{stateLabel .State}}</span>
|
||||||
{{if .Orphaned}}<span class="tag tag-warn">Elavult</span>{{end}}
|
{{if .Orphaned}}<span class="tag tag-warn">{{T "common.elavult"}}</span>{{end}}
|
||||||
{{template "meta_badge" (lifecycleBadge .Meta)}}
|
{{template "meta_badge" (lifecycleBadge .Meta)}}
|
||||||
{{$ms := index $.MissingStorage .Name}}{{if $ms}}<span class="tag tag-warn" title="Az alkalmazás adattárolója nem elérhető. Csatlakoztasd újra a meghajtót, vagy helyezd át az adatokat egy másik tárhelyre."><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>Hiányzó tárhely: {{$ms}}</span>{{end}}
|
{{$ms := index $.MissingStorage .Name}}{{if $ms}}<span class="tag tag-warn" title="{{T "dashboard.az_alkalmazas_adattaroloja_nem_elerheto"}}"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>{{T "dashboard.hianyzo_tarhely"}}</span>{{end}}
|
||||||
{{if $.OOMKilled}}{{if index $.OOMKilled .Name}}<span class="tag tag-warn" title="Az alkalmazás egyik folyamatát a rendszer leállította, mert elfogyott a memóriája. Lehet, hogy egy feladat nem fejeződött be. Indítsd újra az alkalmazást; ha ismétlődik, jelezd az üzemeltetőnek."><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>Memória elfogyott</span>{{end}}{{end}}
|
{{if $.OOMKilled}}{{if index $.OOMKilled .Name}}<span class="tag tag-warn" title="{{T "dashboard.az_alkalmazas_egyik_folyamatat_a"}}"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>{{T "dashboard.memoria_elfogyott"}}</span>{{end}}{{end}}
|
||||||
{{$ns := index $.NetworkStubs .Name}}{{if $ns}}<span class="tag tag-warn" title="Az alkalmazás környezetében a hálózati tárhely helyén üres helyi könyvtár van — az adatok nem a NAS-ra kerülnek. Jelezze az üzemeltetőnek."><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>Hálózati tárhely hibás — az alkalmazás nem a NAS-t látja</span>{{end}}
|
{{$ns := index $.NetworkStubs .Name}}{{if $ns}}<span class="tag tag-warn" title="{{T "dashboard.az_alkalmazas_kornyezeteben_a_halozati"}}"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>{{T "dashboard.halozati_tarhely_hibas_az_alkalmazas"}}</span>{{end}}
|
||||||
{{$nw := index $.NetworkWarnings .Name}}{{if $nw}}<span class="tag tag-warn" title="A hálózati tárhely (NAS) jelenleg nem érhető el. Az alkalmazás fut; az adatok elérése a NAS visszatértével helyreáll."><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>Hálózati tárhely nem elérhető: {{$nw}}</span>{{end}}
|
{{$nw := index $.NetworkWarnings .Name}}{{if $nw}}<span class="tag tag-warn" title="{{T "dashboard.a_halozati_tarhely_nas_jelenleg"}}"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>{{T "dashboard.halozati_tarhely_nem_elerheto"}}</span>{{end}}
|
||||||
{{if and .Deployed (routeUnpublished .State)}}<span class="tag tag-warn" title="A proxy (Traefik) csak egészséges konténerhez publikál nyilvános útvonalat. Amíg az alkalmazás nem egészséges, az URL 404-et ad, pedig a konténer fut."><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>URL nem elérhető</span>{{end}}
|
{{if and .Deployed (routeUnpublished .State)}}<span class="tag tag-warn" title="{{T "dashboard.a_proxy_traefik_csak_egeszseges"}}"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>{{T "dashboard.url_nem_elerheto"}}</span>{{end}}
|
||||||
|
|
||||||
{{if .Protected}}
|
{{if .Protected}}
|
||||||
<span class="tag"><svg class="ico ico-sm"><use href="#i-lock"/></svg>Védett</span>
|
<span class="tag"><svg class="ico ico-sm"><use href="#i-lock"/></svg>{{T "dashboard.vedett"}}</span>
|
||||||
{{/* Customer link ONLY for Linked infra (filebrowser → files.<domain>) —
|
{{/* Customer link ONLY for Linked infra (filebrowser → files.<domain>) —
|
||||||
cloudflared/traefik have no customer UI (guarded by render test). */}}
|
cloudflared/traefik have no customer UI (guarded by render test). */}}
|
||||||
{{if and $im $im.Linked}}
|
{{if and $im $im.Linked}}
|
||||||
{{$subdomain := index $.Subdomains .Name}}
|
{{$subdomain := index $.Subdomains .Name}}
|
||||||
{{if $subdomain}}<a href="https://{{$subdomain}}.{{$.Domain}}{{.Meta.OpenPath}}" target="_blank" class="btn btn-sm btn-outline" onclick="event.stopPropagation()">Megnyitás <svg class="ico ico-sm"><use href="#i-external-link"/></svg></a>{{end}}
|
{{if $subdomain}}<a href="https://{{$subdomain}}.{{$.Domain}}{{.Meta.OpenPath}}" target="_blank" class="btn btn-sm btn-outline" onclick="event.stopPropagation()">{{T "dashboard.megnyitas"}} <svg class="ico ico-sm"><use href="#i-external-link"/></svg></a>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if isOperational .State}}
|
{{if isOperational .State}}
|
||||||
<button class="btn btn-sm btn-warning" onclick="stackAction(event, '{{.Name}}', 'restart')" title="Újraindítás"><svg class="ico ico-sm"><use href="#i-rotate-cw"/></svg></button>
|
<button class="btn btn-sm btn-warning" onclick="stackAction(event, '{{.Name}}', 'restart')" title="{{T "common.ujrainditas"}}"><svg class="ico ico-sm"><use href="#i-rotate-cw"/></svg></button>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else if not .Deployed}}
|
{{else if not .Deployed}}
|
||||||
<a href="/stacks/{{.Name}}/deploy" class="btn btn-sm btn-primary" onclick="return checkBeforeDeploy(event, '{{.Name}}')">Telepítés</a>
|
<a href="/stacks/{{.Name}}/deploy" class="btn btn-sm btn-primary" onclick="return checkBeforeDeploy(event, '{{.Name}}')">{{T "dashboard.telepites"}}</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{if isOperational .State}}
|
{{if isOperational .State}}
|
||||||
{{$subdomain := index $.Subdomains .Name}}
|
{{$subdomain := index $.Subdomains .Name}}
|
||||||
{{if $subdomain}}<a href="https://{{$subdomain}}.{{$.Domain}}{{.Meta.OpenPath}}" target="_blank" class="btn btn-sm btn-outline" onclick="event.stopPropagation()">Megnyitás <svg class="ico ico-sm"><use href="#i-external-link"/></svg></a>{{end}}
|
{{if $subdomain}}<a href="https://{{$subdomain}}.{{$.Domain}}{{.Meta.OpenPath}}" target="_blank" class="btn btn-sm btn-outline" onclick="event.stopPropagation()">{{T "dashboard.megnyitas"}} <svg class="ico ico-sm"><use href="#i-external-link"/></svg></a>{{end}}
|
||||||
<button class="btn btn-sm btn-warning" onclick="stackAction(event, '{{.Name}}', 'restart')" title="Újraindítás"><svg class="ico ico-sm"><use href="#i-rotate-cw"/></svg></button>
|
<button class="btn btn-sm btn-warning" onclick="stackAction(event, '{{.Name}}', 'restart')" title="{{T "common.ujrainditas"}}"><svg class="ico ico-sm"><use href="#i-rotate-cw"/></svg></button>
|
||||||
<button class="btn btn-sm btn-danger" onclick="stackAction(event, '{{.Name}}', 'stop')" title="Leállítás"><svg class="ico ico-sm"><use href="#i-square"/></svg></button>
|
<button class="btn btn-sm btn-danger" onclick="stackAction(event, '{{.Name}}', 'stop')" title="{{T "dashboard.leallitas"}}"><svg class="ico ico-sm"><use href="#i-square"/></svg></button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<button class="btn btn-sm btn-success" onclick="stackAction(event, '{{.Name}}', 'start')" title="Indítás"><svg class="ico ico-sm"><use href="#i-play"/></svg></button>
|
<button class="btn btn-sm btn-success" onclick="stackAction(event, '{{.Name}}', 'start')" title="{{T "dashboard.inditas"}}"><svg class="ico ico-sm"><use href="#i-play"/></svg></button>
|
||||||
{{if not .Orphaned}}<button class="btn btn-sm btn-danger" onclick="removeStack('{{.Name}}')">Eltávolítás</button>{{end}}
|
{{if not .Orphaned}}<button class="btn btn-sm btn-danger" onclick="removeStack('{{.Name}}')">{{T "common.eltavolitas"}}</button>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<a href="/stacks/{{.Name}}/logs" class="btn btn-sm btn-outline">Napló</a>
|
<a href="/stacks/{{.Name}}/logs" class="btn btn-sm btn-outline">{{T "dashboard.naplo"}}</a>
|
||||||
{{if .Orphaned}}<button class="btn btn-sm btn-danger" onclick="deleteOrphanStack('{{.Name}}')">Törlés</button>{{end}}
|
{{if .Orphaned}}<button class="btn btn-sm btn-danger" onclick="deleteOrphanStack('{{.Name}}')">{{T "common.torles"}}</button>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{template "app_list_row_end"}}
|
{{template "app_list_row_end"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="empty-state">
|
<div class="empty-state">
|
||||||
<p>Nincs elérhető alkalmazás.</p>
|
<p>{{T "dashboard.nincs_elerheto_alkalmazas"}}</p>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,22 +3,22 @@
|
|||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<div style="display:flex;align-items:center;gap:.5rem">
|
<div style="display:flex;align-items:center;gap:.5rem">
|
||||||
<a href="/stacks" class="btn btn-sm btn-outline">← Vissza</a>
|
<a href="/stacks" class="btn btn-sm btn-outline">{{T "deploy.vissza"}}</a>
|
||||||
<h2>{{.Meta.DisplayName}} — {{if .AlreadyDeployed}}Beállítások{{else}}Telepítés{{end}}</h2>
|
<h2>{{.Meta.DisplayName}} — {{if .AlreadyDeployed}}{{T "deploy.beallitasok"}}{{else}}{{T "deploy.telepites"}}{{end}}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;align-items:center;gap:.5rem">
|
<div style="display:flex;align-items:center;gap:.5rem">
|
||||||
{{if .AlreadyDeployed}}
|
{{if .AlreadyDeployed}}
|
||||||
{{if isOperational .Stack.State}}
|
{{if isOperational .Stack.State}}
|
||||||
<button class="btn btn-sm btn-warning" onclick="stackAction(event, '{{.Stack.Name}}', 'restart')">Újraindítás</button>
|
<button class="btn btn-sm btn-warning" onclick="stackAction(event, '{{.Stack.Name}}', 'restart')">{{T "common.ujrainditas"}}</button>
|
||||||
<button class="btn btn-sm btn-danger" onclick="stackAction(event, '{{.Stack.Name}}', 'stop')">Leállítás</button>
|
<button class="btn btn-sm btn-danger" onclick="stackAction(event, '{{.Stack.Name}}', 'stop')">{{T "deploy.leallitas"}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
<button class="btn btn-sm btn-success" onclick="stackAction(event, '{{.Stack.Name}}', 'start')">Indítás</button>
|
<button class="btn btn-sm btn-success" onclick="stackAction(event, '{{.Stack.Name}}', 'start')">{{T "deploy.inditas"}}</button>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and (isOperational .Stack.State) .EffectiveSubdomain}}
|
{{if and (isOperational .Stack.State) .EffectiveSubdomain}}
|
||||||
<a href="https://{{.EffectiveSubdomain}}.{{.Domain}}{{.Meta.OpenPath}}" target="_blank" class="btn btn-sm btn-outline">Megnyitás ↗</a>
|
<a href="https://{{.EffectiveSubdomain}}.{{.Domain}}{{.Meta.OpenPath}}" target="_blank" class="btn btn-sm btn-outline">{{T "deploy.megnyitas"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<a href="/apps/{{.Meta.Slug}}" class="btn btn-sm btn-outline"><svg class="ico ico-sm"><use href="#i-info"/></svg> Részletek</a>
|
<a href="/apps/{{.Meta.Slug}}" class="btn btn-sm btn-outline"><svg class="ico ico-sm"><use href="#i-info"/></svg> {{T "deploy.reszletek"}}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -33,73 +33,72 @@
|
|||||||
{{if .Meta.Description}}<p>{{.Meta.Description}}</p>{{end}}
|
{{if .Meta.Description}}<p>{{.Meta.Description}}</p>{{end}}
|
||||||
<div class="metarows">
|
<div class="metarows">
|
||||||
{{if .Meta.Resources.MemRequest}}<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~{{.Meta.Resources.MemRequest}}</span></span>{{end}}
|
{{if .Meta.Resources.MemRequest}}<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~{{.Meta.Resources.MemRequest}}</span></span>{{end}}
|
||||||
{{if .Meta.Resources.PiCompatible}}<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>{{end}}
|
{{if .Meta.Resources.PiCompatible}}<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>{{T "common.pi_kompatibilis"}}</span>{{end}}
|
||||||
{{if .Meta.Resources.NeedsHDD}}<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>{{end}}
|
{{if .Meta.Resources.NeedsHDD}}<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>{{T "common.hdd_szukseges"}}</span>{{end}}
|
||||||
{{if .Meta.Resources.HungarianUI}}<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Magyar felület</span>{{end}}
|
{{if .Meta.Resources.HungarianUI}}<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>{{T "common.magyar_felulet"}}</span>{{end}}
|
||||||
</div>
|
</div>
|
||||||
<a href="/apps/{{.Meta.Slug}}" class="btn btn-sm btn-outline" style="margin-top:0.5rem">
|
<a href="/apps/{{.Meta.Slug}}" class="btn btn-sm btn-outline" style="margin-top:0.5rem">
|
||||||
Részletes leírás, képernyőképek
|
{{T "deploy.reszletes_leiras_kepernyokepek"}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if .AlreadyDeployed}}
|
{{if .AlreadyDeployed}}
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
Ez az alkalmazás már telepítve van. Az alábbi beállítások csak olvashatók.
|
{{T "deploy.ez_az_alkalmazas_mar_telepitve"}}
|
||||||
</div>
|
</div>
|
||||||
{{if .StorageInfo}}
|
{{if .StorageInfo}}
|
||||||
<div class="deploy-storage-info">
|
<div class="deploy-storage-info">
|
||||||
<h4>Adattárolás</h4>
|
<h4>{{T "deploy.adattarolas"}}</h4>
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Tárhely</span>
|
<span class="settings-label">{{T "deploy.tarhely"}}</span>
|
||||||
<span class="settings-value">{{.StorageInfo.Label}} <span class="mono" style="color:var(--text-2)">({{.StorageInfo.Path}})</span></span>
|
<span class="settings-value">{{.StorageInfo.Label}} <span class="mono" style="color:var(--text-2)">({{.StorageInfo.Path}})</span></span>
|
||||||
</div>
|
</div>
|
||||||
{{if .StorageInfo.DataSizeHuman}}
|
{{if .StorageInfo.DataSizeHuman}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Adatméret</span>
|
<span class="settings-label">{{T "deploy.adatmeret"}}</span>
|
||||||
<span class="settings-value mono">{{.StorageInfo.DataSizeHuman}}</span>
|
<span class="settings-value mono">{{.StorageInfo.DataSizeHuman}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .StorageInfo.FreeHuman}}
|
{{if .StorageInfo.FreeHuman}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Szabad hely</span>
|
<span class="settings-label">{{T "deploy.szabad_hely"}}</span>
|
||||||
<span class="settings-value mono">{{.StorageInfo.FreeHuman}} ({{printf "%.0f" .StorageInfo.FreePercent}}% szabad)</span>
|
<span class="settings-value mono">{{T "deploy.szabad"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{if .OtherStoragePaths}}
|
{{if .OtherStoragePaths}}
|
||||||
<span class="btn btn-sm btn-outline" style="margin-top:.75rem;opacity:.45;cursor:not-allowed" title="Hamarosan">
|
<span class="btn btn-sm btn-outline" style="margin-top:.75rem;opacity:.45;cursor:not-allowed" title="{{T "deploy.hamarosan"}}">
|
||||||
<svg class="ico ico-sm"><use href="#i-upload"/></svg> Mozgatás másik tárolóra
|
<svg class="ico ico-sm"><use href="#i-upload"/></svg> {{T "deploy.mozgatas_masik_tarolora"}}
|
||||||
</span>
|
</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .StaleData}}
|
{{if .StaleData}}
|
||||||
<div class="deploy-stale-data">
|
<div class="deploy-stale-data">
|
||||||
<h4>Korábbi adatok</h4>
|
<h4>{{T "deploy.korabbi_adatok"}}</h4>
|
||||||
<p class="form-hint" style="margin-bottom:1rem">
|
<p class="form-hint" style="margin-bottom:1rem">
|
||||||
Az alkalmazás adatainak másolata megtalálható egy másik tárolón is.
|
{{T "deploy.az_alkalmazas_adatainak_masolata_megtala"}}
|
||||||
Ez általában áthelyezés után marad hátra.
|
|
||||||
</p>
|
</p>
|
||||||
{{range .StaleData}}
|
{{range .StaleData}}
|
||||||
<div class="stale-data-item">
|
<div class="stale-data-item">
|
||||||
<div class="settings-grid" style="margin-bottom:.75rem">
|
<div class="settings-grid" style="margin-bottom:.75rem">
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Tárhely</span>
|
<span class="settings-label">{{T "deploy.tarhely"}}</span>
|
||||||
<span class="settings-value">{{.Label}} <span class="mono" style="color:var(--text-2)">({{.Path}})</span></span>
|
<span class="settings-value">{{.Label}} <span class="mono" style="color:var(--text-2)">({{.Path}})</span></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Méret</span>
|
<span class="settings-label">{{T "deploy.meret"}}</span>
|
||||||
<span class="settings-value mono">{{.SizeHuman}}</span>
|
<span class="settings-value mono">{{.SizeHuman}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Mappák</span>
|
<span class="settings-label">{{T "deploy.mappak"}}</span>
|
||||||
<span class="settings-value mono" style="font-size:.85rem">{{range .Mounts}}{{.}}<br>{{end}}</span>
|
<span class="settings-value mono" style="font-size:.85rem">{{range .Mounts}}{{.}}<br>{{end}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-sm btn-danger" onclick="deleteStaleData('{{$.Meta.Slug}}', '{{.Path}}', this)">
|
<button class="btn btn-sm btn-danger" onclick="deleteStaleData('{{$.Meta.Slug}}', '{{.Path}}', this)">
|
||||||
Korábbi adatok törlése
|
{{T "deploy.korabbi_adatok_torlese"}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -109,12 +108,11 @@
|
|||||||
|
|
||||||
{{if .AlreadyDeployed}}
|
{{if .AlreadyDeployed}}
|
||||||
<div class="deploy-cross-drive">
|
<div class="deploy-cross-drive">
|
||||||
<h4>Biztonsági mentés</h4>
|
<h4>{{T "deploy.biztonsagi_mentes"}}</h4>
|
||||||
|
|
||||||
<div class="cross-drive-nightly">
|
<div class="cross-drive-nightly">
|
||||||
<span class="form-hint" style="display:block;margin-top:.25rem">
|
<span class="form-hint" style="display:block;margin-top:.25rem">
|
||||||
Az alkalmazás adatbázisa és Docker kötetei automatikusan bekerülnek az éjszakai biztonsági mentésbe.
|
{{T "deploy.az_alkalmazas_adatbazisa_es_docker"}}
|
||||||
<a href="/backups" style="color:var(--blue)">Mentési állapot →</a> · <a href="/stacks/{{.Stack.Name}}/backup" style="color:var(--blue)">Mentési beállítások →</a>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -122,9 +120,9 @@
|
|||||||
|
|
||||||
{{if .HasIntegrations}}
|
{{if .HasIntegrations}}
|
||||||
<div class="app-optional-config">
|
<div class="app-optional-config">
|
||||||
<h3>Integrációk</h3>
|
<h3>{{T "deploy.integraciok"}}</h3>
|
||||||
<p class="config-group-desc">
|
<p class="config-group-desc">
|
||||||
Más telepített alkalmazásokkal való összekapcsolás. Az integráció automatikusan felfüggesztődik, ha bármelyik alkalmazás leáll, és újraaktiválódik indításkor.
|
{{T "deploy.mas_telepitett_alkalmazasokkal_valo_ossz"}}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{{range .Integrations}}
|
{{range .Integrations}}
|
||||||
@@ -133,20 +131,20 @@
|
|||||||
<strong>{{.Label}}</strong>
|
<strong>{{.Label}}</strong>
|
||||||
<p class="config-field-help" style="margin:0">{{.Description}}</p>
|
<p class="config-field-help" style="margin:0">{{.Description}}</p>
|
||||||
{{if not .TargetDeployed}}
|
{{if not .TargetDeployed}}
|
||||||
<span class="tag tag-off" style="margin-top:.25rem"><span class="dot"></span>Nincs telepítve</span>
|
<span class="tag tag-off" style="margin-top:.25rem"><span class="dot"></span>{{T "deploy.nincs_telepitve"}}</span>
|
||||||
{{else if not .TargetRunning}}
|
{{else if not .TargetRunning}}
|
||||||
<span class="tag tag-neutral" style="margin-top:.25rem"><span class="dot"></span>Célalkalmazás leállítva</span>
|
<span class="tag tag-neutral" style="margin-top:.25rem"><span class="dot"></span>{{T "deploy.celalkalmazas_leallitva"}}</span>
|
||||||
{{else if eq .Status "error"}}
|
{{else if eq .Status "error"}}
|
||||||
<span class="tag tag-crit" style="margin-top:.25rem"><span class="dot"></span>Hiba</span>
|
<span class="tag tag-crit" style="margin-top:.25rem"><span class="dot"></span>{{T "common.hiba"}}</span>
|
||||||
{{else if .Enabled}}
|
{{else if .Enabled}}
|
||||||
<span class="tag tag-run" style="margin-top:.25rem"><span class="dot"></span>Aktív</span>
|
<span class="tag tag-run" style="margin-top:.25rem"><span class="dot"></span>{{T "deploy.aktiv"}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
{{if .Enabled}}checked{{end}}
|
{{if .Enabled}}checked{{end}}
|
||||||
{{if not .TargetDeployed}}disabled title="A célalkalmazás nincs telepítve"{{end}}
|
{{if not .TargetDeployed}}disabled title="{{T "deploy.a_celalkalmazas_nincs_telepitve"}}"{{end}}
|
||||||
{{if and .TargetDeployed (not .TargetRunning)}}disabled title="A célalkalmazás nem fut"{{end}}
|
{{if and .TargetDeployed (not .TargetRunning)}}disabled title="{{T "deploy.a_celalkalmazas_nem_fut"}}"{{end}}
|
||||||
onchange="toggleIntegration('{{$.Stack.Name}}', '{{.Target}}', this.checked, this)">
|
onchange="toggleIntegration('{{$.Stack.Name}}', '{{.Target}}', this.checked, this)">
|
||||||
<span class="toggle-label"></span>
|
<span class="toggle-label"></span>
|
||||||
</label>
|
</label>
|
||||||
@@ -166,14 +164,14 @@
|
|||||||
var data = await resp.json();
|
var data = await resp.json();
|
||||||
if (!data.ok) {
|
if (!data.ok) {
|
||||||
checkbox.checked = !enable;
|
checkbox.checked = !enable;
|
||||||
showAlert(data.error || 'Hiba történt');
|
showAlert(data.error || '{{T "common.hiba_tortent"}}');
|
||||||
} else {
|
} else {
|
||||||
setTimeout(function(){ location.reload(); }, 500);
|
setTimeout(function(){ location.reload(); }, 500);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
checkbox.checked = !enable;
|
checkbox.checked = !enable;
|
||||||
showAlert('Hálózati hiba');
|
showAlert('{{T "deploy.halozati_hiba"}}');
|
||||||
}
|
}
|
||||||
checkbox.disabled = false;
|
checkbox.disabled = false;
|
||||||
}
|
}
|
||||||
@@ -182,24 +180,24 @@
|
|||||||
|
|
||||||
{{if .GeoGlobalEnabled}}
|
{{if .GeoGlobalEnabled}}
|
||||||
<div class="app-optional-config">
|
<div class="app-optional-config">
|
||||||
<h3>Földrajzi korlátozás</h3>
|
<h3>{{T "deploy.foldrajzi_korlatozas"}}</h3>
|
||||||
<p class="config-group-desc">
|
<p class="config-group-desc">
|
||||||
Az alkalmazás egyéni országkorlátozás nélkül a globális beállítást követi.
|
{{T "deploy.az_alkalmazas_egyeni_orszagkorlatozas_ne"}}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<label class="toggle" style="margin-bottom:1rem">
|
<label class="toggle" style="margin-bottom:1rem">
|
||||||
<input type="checkbox" id="app-geo-override-toggle"
|
<input type="checkbox" id="app-geo-override-toggle"
|
||||||
{{if .GeoAppOverride}}checked{{end}}
|
{{if .GeoAppOverride}}checked{{end}}
|
||||||
onchange="toggleAppGeoOverride(this.checked)">
|
onchange="toggleAppGeoOverride(this.checked)">
|
||||||
<span class="toggle-label">Egyéni országkorlátozás</span>
|
<span class="toggle-label">{{T "deploy.egyeni_orszagkorlatozas"}}</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div id="app-geo-override-details" {{if not .GeoAppOverride}}style="display:none"{{end}}>
|
<div id="app-geo-override-details" {{if not .GeoAppOverride}}style="display:none"{{end}}>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Engedélyezett országok ehhez az alkalmazáshoz</label>
|
<label>{{T "deploy.engedelyezett_orszagok_ehhez_az_alkalmaz"}}</label>
|
||||||
<div class="geo-country-selector">
|
<div class="geo-country-selector">
|
||||||
<input type="text" id="app-geo-search" class="form-control config-input"
|
<input type="text" id="app-geo-search" class="form-control config-input"
|
||||||
placeholder="Ország keresése..." autocomplete="off"
|
placeholder="{{T "deploy.orszag_keresese"}}" autocomplete="off"
|
||||||
oninput="filterAppGeoCountries(this.value)"
|
oninput="filterAppGeoCountries(this.value)"
|
||||||
onfocus="showAppGeoList()"
|
onfocus="showAppGeoList()"
|
||||||
onblur="setTimeout(function(){hideAppGeoList()},200)">
|
onblur="setTimeout(function(){hideAppGeoList()},200)">
|
||||||
@@ -208,7 +206,7 @@
|
|||||||
<div class="geo-selected-tags" id="app-geo-tags"></div>
|
<div class="geo-selected-tags" id="app-geo-tags"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="config-actions">
|
<div class="config-actions">
|
||||||
<button class="btn btn-primary" onclick="saveAppGeoOverride()">Mentés</button>
|
<button class="btn btn-primary" onclick="saveAppGeoOverride()">{{T "deploy.mentes"}}</button>
|
||||||
<span id="app-geo-status" class="config-save-status"></span>
|
<span id="app-geo-status" class="config-save-status"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -255,7 +253,7 @@
|
|||||||
+ esc(c.name) + ' <small>(' + c.code + ')</small></div>';
|
+ esc(c.name) + ' <small>(' + c.code + ')</small></div>';
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
list.innerHTML = html || '<div class="geo-country-option" style="opacity:.5">Nincs találat</div>';
|
list.innerHTML = html || '<div class="geo-country-option" style="opacity:.5">{{T "deploy.nincs_talalat"}}</div>';
|
||||||
list.style.display = (count > 0 || q) ? '' : 'none';
|
list.style.display = (count > 0 || q) ? '' : 'none';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -296,12 +294,12 @@
|
|||||||
})
|
})
|
||||||
.then(function(r){return r.json()})
|
.then(function(r){return r.json()})
|
||||||
.then(function(d){
|
.then(function(d){
|
||||||
status.textContent = d.ok ? (d.message || 'Mentve') : (d.error || 'Hiba');
|
status.textContent = d.ok ? (d.message || '{{T "deploy.mentve"}}') : (d.error || '{{T "common.hiba"}}');
|
||||||
status.className = 'config-save-status ' + (d.ok ? 'config-save-ok' : 'config-save-err');
|
status.className = 'config-save-status ' + (d.ok ? 'config-save-ok' : 'config-save-err');
|
||||||
setTimeout(function(){ status.textContent=''; }, 5000);
|
setTimeout(function(){ status.textContent=''; }, 5000);
|
||||||
})
|
})
|
||||||
.catch(function(){
|
.catch(function(){
|
||||||
status.textContent = 'Hálózati hiba';
|
status.textContent = '{{T "deploy.halozati_hiba"}}';
|
||||||
status.className = 'config-save-status config-save-err';
|
status.className = 'config-save-status config-save-err';
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -317,7 +315,7 @@
|
|||||||
|
|
||||||
{{if .HasOptionalConfig}}
|
{{if .HasOptionalConfig}}
|
||||||
<div class="app-optional-config">
|
<div class="app-optional-config">
|
||||||
<h3>Opcionális beállítások</h3>
|
<h3>{{T "deploy.opcionalis_beallitasok"}}</h3>
|
||||||
{{range .OptionalConfig}}
|
{{range .OptionalConfig}}
|
||||||
<div class="config-group">
|
<div class="config-group">
|
||||||
<h4>{{.Group}}</h4>
|
<h4>{{.Group}}</h4>
|
||||||
@@ -328,7 +326,7 @@
|
|||||||
<div class="config-field">
|
<div class="config-field">
|
||||||
<label for="opt-{{.EnvVar}}">{{.Label}}</label>
|
<label for="opt-{{.EnvVar}}">{{.Label}}</label>
|
||||||
{{if .HelpText}}<p class="config-field-help">{{.HelpText}}</p>{{end}}
|
{{if .HelpText}}<p class="config-field-help">{{.HelpText}}</p>{{end}}
|
||||||
{{if .HelpURL}}<p class="config-field-help"><a href="{{.HelpURL}}" target="_blank">Regisztrációs útmutató ↗</a></p>{{end}}
|
{{if .HelpURL}}<p class="config-field-help"><a href="{{.HelpURL}}" target="_blank">{{T "deploy.regisztracios_utmutato"}}</a></p>{{end}}
|
||||||
<input type="{{if eq .Type "secret_input"}}password{{else}}text{{end}}"
|
<input type="{{if eq .Type "secret_input"}}password{{else}}text{{end}}"
|
||||||
id="opt-{{.EnvVar}}"
|
id="opt-{{.EnvVar}}"
|
||||||
name="{{.EnvVar}}"
|
name="{{.EnvVar}}"
|
||||||
@@ -344,7 +342,7 @@
|
|||||||
|
|
||||||
<div class="config-actions">
|
<div class="config-actions">
|
||||||
<button class="btn btn-primary" id="save-optional-config" onclick="saveOptionalConfig('{{.Stack.Name}}')">
|
<button class="btn btn-primary" id="save-optional-config" onclick="saveOptionalConfig('{{.Stack.Name}}')">
|
||||||
Mentés
|
{{T "deploy.mentes"}}
|
||||||
</button>
|
</button>
|
||||||
<span id="config-save-status" class="config-save-status"></span>
|
<span id="config-save-status" class="config-save-status"></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -362,7 +360,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.textContent = 'Mentés...';
|
btn.textContent = '{{T "deploy.mentes_2"}}';
|
||||||
status.textContent = '';
|
status.textContent = '';
|
||||||
status.className = 'config-save-status';
|
status.className = 'config-save-status';
|
||||||
|
|
||||||
@@ -375,19 +373,19 @@
|
|||||||
var data = await resp.json();
|
var data = await resp.json();
|
||||||
|
|
||||||
if (data.ok) {
|
if (data.ok) {
|
||||||
status.textContent = (data.message || 'Mentve');
|
status.textContent = (data.message || '{{T "deploy.mentve"}}');
|
||||||
status.className = 'config-save-status config-save-ok';
|
status.className = 'config-save-status config-save-ok';
|
||||||
} else {
|
} else {
|
||||||
status.textContent = (data.error || 'Hiba');
|
status.textContent = (data.error || '{{T "common.hiba"}}');
|
||||||
status.className = 'config-save-status config-save-err';
|
status.className = 'config-save-status config-save-err';
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
status.textContent = 'Hálózati hiba';
|
status.textContent = '{{T "deploy.halozati_hiba"}}';
|
||||||
status.className = 'config-save-status config-save-err';
|
status.className = 'config-save-status config-save-err';
|
||||||
}
|
}
|
||||||
|
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = 'Mentés';
|
btn.textContent = '{{T "deploy.mentes"}}';
|
||||||
|
|
||||||
setTimeout(function() { status.textContent = ''; }, 5000);
|
setTimeout(function() { status.textContent = ''; }, 5000);
|
||||||
}
|
}
|
||||||
@@ -396,26 +394,24 @@
|
|||||||
|
|
||||||
{{if .AppEmailSupported}}
|
{{if .AppEmailSupported}}
|
||||||
<div class="app-optional-config">
|
<div class="app-optional-config">
|
||||||
<h3>Email-küldés</h3>
|
<h3>{{T "deploy.email_kuldes"}}</h3>
|
||||||
<p class="config-group-desc">
|
<p class="config-group-desc">
|
||||||
Ez az alkalmazás tud emailt küldeni (pl. jelszó-visszaállítás, meghívók) a Felhom-on keresztül,
|
{{T "deploy.ez_az_alkalmazas_tud_emailt"}}
|
||||||
külön szolgáltató beállítása nélkül. A feladó címe: <strong>{{.AppEmailFromAddress}}</strong>.
|
|
||||||
</p>
|
</p>
|
||||||
{{if not .AppEmailGlobalOn}}
|
{{if not .AppEmailGlobalOn}}
|
||||||
<p class="alert alert-warning" style="margin-bottom:1rem">
|
<p class="alert alert-warning" style="margin-bottom:1rem">
|
||||||
Az alkalmazás-email jelenleg ki van kapcsolva globálisan. Kapcsold be a
|
{{T "deploy.az_alkalmazas_email_jelenleg_ki"}}
|
||||||
<a href="/settings">Beállítások</a> oldalon, hogy itt is működjön.
|
|
||||||
</p>
|
</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
<form method="POST" action="/stacks/{{.Stack.Name}}/app-email">
|
<form method="POST" action="/stacks/{{.Stack.Name}}/app-email">
|
||||||
{{$.CSRFField}}
|
{{$.CSRFField}}
|
||||||
<label style="display:flex;align-items:center;gap:.5rem;margin-bottom:1rem">
|
<label style="display:flex;align-items:center;gap:.5rem;margin-bottom:1rem">
|
||||||
<input type="checkbox" name="app_email_enabled" value="on" {{if .AppEmailAppOn}}checked{{end}}>
|
<input type="checkbox" name="app_email_enabled" value="on" {{if .AppEmailAppOn}}checked{{end}}>
|
||||||
Email-küldés engedélyezése ennél az alkalmazásnál
|
{{T "deploy.email_kuldes_engedelyezese_ennel_az"}}
|
||||||
</label>
|
</label>
|
||||||
<div class="config-actions">
|
<div class="config-actions">
|
||||||
<button class="btn btn-primary" type="submit">Mentés</button>
|
<button class="btn btn-primary" type="submit">{{T "deploy.mentes"}}</button>
|
||||||
<span class="config-group-desc" style="margin-left:.5rem">A mentés újraindítja az alkalmazást.</span>
|
<span class="config-group-desc" style="margin-left:.5rem">{{T "deploy.a_mentes_ujrainditja_az_alkalmazast"}}</span>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -427,25 +423,24 @@
|
|||||||
<div class="memory-summary{{if .Blocked}} memory-blocked{{end}}">
|
<div class="memory-summary{{if .Blocked}} memory-blocked{{end}}">
|
||||||
{{if .Blocked}}
|
{{if .Blocked}}
|
||||||
<div class="alert alert-error" style="margin-bottom:0">
|
<div class="alert alert-error" style="margin-bottom:0">
|
||||||
Nincs elég memória! Foglalás telepítés után: {{.AfterMB}} MB / {{.UsableMB}} MB
|
{{T "deploy.nincs_eleg_memoria_foglalas_telepites"}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="memory-summary-header">
|
<div class="memory-summary-header">
|
||||||
<span class="memory-summary-label">Memória</span>
|
<span class="memory-summary-label">{{T "deploy.memoria"}}</span>
|
||||||
<span class="memory-summary-value">{{.AfterMB}} MB / {{.UsableMB}} MB ({{.Percent}}%)</span>
|
<span class="memory-summary-value">{{.AfterMB}} MB / {{.UsableMB}} MB ({{.Percent}}%)</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="meter-track meter-track-stacked">
|
<div class="meter-track meter-track-stacked">
|
||||||
<div class="memory-bar-segment memory-bar-committed" style="width:{{.UsedPercent}}%" title="Jelenlegi használat: {{.UsedMB}} MB"></div>
|
<div class="memory-bar-segment memory-bar-committed" style="width:{{.UsedPercent}}%" title="{{T "deploy.jelenlegi_hasznalat_mb"}}"></div>
|
||||||
<div class="memory-bar-segment memory-bar-new" style="width:{{subtract .Percent .UsedPercent}}%" title="{{$.Meta.DisplayName}}: +{{.NewRequestMB}} MB"></div>
|
<div class="memory-bar-segment memory-bar-new" style="width:{{subtract .Percent .UsedPercent}}%" title="{{$.Meta.DisplayName}}: +{{.NewRequestMB}} MB"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="memory-bar-legend">
|
<div class="memory-bar-legend">
|
||||||
<span class="memory-legend-item"><span class="memory-legend-dot memory-legend-committed"></span>Jelenlegi használat ({{.UsedMB}} MB)</span>
|
<span class="memory-legend-item"><span class="memory-legend-dot memory-legend-committed"></span>{{T "deploy.jelenlegi_hasznalat_mb_2"}}</span>
|
||||||
<span class="memory-legend-item"><span class="memory-legend-dot memory-legend-new"></span>{{$.Meta.DisplayName}} (+{{.NewRequestMB}} MB)</span>
|
<span class="memory-legend-item"><span class="memory-legend-dot memory-legend-new"></span>{{$.Meta.DisplayName}} (+{{.NewRequestMB}} MB)</span>
|
||||||
</div>
|
</div>
|
||||||
{{if .OvercommitWarn}}
|
{{if .OvercommitWarn}}
|
||||||
<div class="alert alert-warning" style="margin-top:0.5rem;margin-bottom:0">
|
<div class="alert alert-warning" style="margin-top:0.5rem;margin-bottom:0">
|
||||||
Az alkalmazások csúcsterhelése meghaladhatja a rendelkezésre álló memóriát.
|
{{T "deploy.az_alkalmazasok_csucsterhelese_meghaladh"}}
|
||||||
Normál használat mellett ez nem okoz problémát.
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -461,10 +456,10 @@
|
|||||||
{{if and (not .AlreadyDeployed) .RestoreHasRecord}}
|
{{if and (not .AlreadyDeployed) .RestoreHasRecord}}
|
||||||
<div class="alert alert-info" style="margin-bottom:1rem">
|
<div class="alert alert-info" style="margin-bottom:1rem">
|
||||||
<svg class="ico ico-sm"><use href="#i-info"/></svg>
|
<svg class="ico ico-sm"><use href="#i-info"/></svg>
|
||||||
Ennek az alkalmazásnak van korábbi mentése, ezért az alábbi mezőket a saját mentése alapján töltöttük ki.
|
{{T "deploy.ennek_az_alkalmazasnak_van_korabbi"}}
|
||||||
{{if .RestoreRecordedAddress}}Korábbi webcím: <strong>{{.RestoreRecordedAddress}}</strong>.{{end}}
|
{{if .RestoreRecordedAddress}}{{T "deploy.korabbi_webcim"}}{{end}}
|
||||||
{{if .RestoreRecordedDrive}}Az adatai itt voltak: <strong>{{.RestoreRecordedDrive}}</strong>.{{end}}
|
{{if .RestoreRecordedDrive}}{{T "deploy.az_adatai_itt_voltak"}}{{end}}
|
||||||
Ha most máshová szeretnéd telepíteni, nyugodtan átírhatod — a visszaállítás előtt jelezni fogjuk az eltérést.
|
{{T "deploy.ha_most_mashova_szeretned_telepiteni"}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{/* R-351 / Part 1 — WHERE THE DATA WILL LIVE, before the button is pressed. Measured
|
{{/* R-351 / Part 1 — WHERE THE DATA WILL LIVE, before the button is pressed. Measured
|
||||||
@@ -474,27 +469,24 @@
|
|||||||
{{if not .AlreadyDeployed}}
|
{{if not .AlreadyDeployed}}
|
||||||
<div class="form-hint" style="margin-bottom:1rem">
|
<div class="form-hint" style="margin-bottom:1rem">
|
||||||
{{if .RestoreRecordedDeclaresPath}}
|
{{if .RestoreRecordedDeclaresPath}}
|
||||||
Az alkalmazás adatai az alább kiválasztott adatmeghajtóra kerülnek.
|
{{T "deploy.az_alkalmazas_adatai_az_alabb"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<strong>Hol lesznek az adatok:</strong> ennél az alkalmazásnál nincs külön adatmeghajtó-választás,
|
{{T "deploy.hol_lesznek_az_adatok_ennel"}}
|
||||||
ezért az adatai a rendszermeghajtóra kerülnek (<code>{{.SystemDataPath}}</code>). A mentései így is elkészülnek.
|
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .DockerBelowReserve}}
|
{{if .DockerBelowReserve}}
|
||||||
<div class="alert alert-warning" style="margin-bottom:1rem">
|
<div class="alert alert-warning" style="margin-bottom:1rem">
|
||||||
<svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> Nincs elég szabad tárhely a telepítéshez. Jelenleg {{.DockerFreeHuman}} szabad, és a rendszer
|
<svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> {{T "deploy.nincs_eleg_szabad_tarhely_a"}}
|
||||||
{{.DockerReserveHuman}} tartalékot tart fenn az alapszolgáltatások (vezérlő, proxy) védelmében.
|
|
||||||
A telepítés ezért átmenetileg le van tiltva — szabadítson fel helyet, vagy bővítse a tárhelyet.
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .AutoFields}}
|
{{if .AutoFields}}
|
||||||
<div class="form-section">
|
<div class="form-section">
|
||||||
<h4>Automatikusan generált értékek</h4>
|
<h4>{{T "deploy.automatikusan_generalt_ertekek"}}</h4>
|
||||||
{{if .AlreadyDeployed}}
|
{{if .AlreadyDeployed}}
|
||||||
<p class="form-section-desc">Ezek az értékek automatikusan jöttek létre a telepítéskor.</p>
|
<p class="form-section-desc">{{T "deploy.ezek_az_ertekek_automatikusan_jottek"}}</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
<p class="form-section-desc">Ezek az értékek a telepítéssel együtt mentésre kerülnek. Jegyezze fel a szükséges jelszavakat!</p>
|
<p class="form-section-desc">{{T "deploy.ezek_az_ertekek_a_telepitessel"}}</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{$autoValues := .AutoFieldValues}}
|
{{$autoValues := .AutoFieldValues}}
|
||||||
{{$stackName := .Stack.Name}}
|
{{$stackName := .Stack.Name}}
|
||||||
@@ -502,7 +494,7 @@
|
|||||||
{{range .AutoFields}}
|
{{range .AutoFields}}
|
||||||
{{$val := index $autoValues .EnvVar}}
|
{{$val := index $autoValues .EnvVar}}
|
||||||
<div class="form-group form-group-auto">
|
<div class="form-group form-group-auto">
|
||||||
<label>{{.Label}} {{if eq .Type "secret"}}<span class="auto-generated-badge"><svg class="ico ico-sm"><use href="#i-check"/></svg> Automatikusan generálva</span>{{end}}</label>
|
<label>{{.Label}} {{if eq .Type "secret"}}<span class="auto-generated-badge"><svg class="ico ico-sm"><use href="#i-check"/></svg> {{T "deploy.automatikusan_generalva"}}</span>{{end}}</label>
|
||||||
{{if $val}}
|
{{if $val}}
|
||||||
{{if eq .Type "secret"}}
|
{{if eq .Type "secret"}}
|
||||||
{{if $isDeployed}}
|
{{if $isDeployed}}
|
||||||
@@ -512,12 +504,12 @@
|
|||||||
submits, so the saved value is the one the customer was shown (README §318). -->
|
submits, so the saved value is the one the customer was shown (README §318). -->
|
||||||
<div class="input-with-button">
|
<div class="input-with-button">
|
||||||
<input type="password" id="auto-field-{{.EnvVar}}" class="form-control" value="" placeholder="••••••••••••" readonly>
|
<input type="password" id="auto-field-{{.EnvVar}}" class="form-control" value="" placeholder="••••••••••••" readonly>
|
||||||
<button type="button" class="btn btn-sm btn-outline" onclick="revealAutoField('{{$stackName}}','{{.EnvVar}}', this)">Megjelenítés</button>
|
<button type="button" class="btn btn-sm btn-outline" onclick="revealAutoField('{{$stackName}}','{{.EnvVar}}', this)">{{T "deploy.megjelenites"}}</button>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="input-with-button">
|
<div class="input-with-button">
|
||||||
<input type="password" id="auto-field-{{.EnvVar}}" class="form-control" value="{{$val}}" readonly>
|
<input type="password" id="auto-field-{{.EnvVar}}" class="form-control" value="{{$val}}" readonly>
|
||||||
<button type="button" class="btn btn-sm btn-outline" onclick="toggleAutoField('auto-field-{{.EnvVar}}', this)">Megjelenítés</button>
|
<button type="button" class="btn btn-sm btn-outline" onclick="toggleAutoField('auto-field-{{.EnvVar}}', this)">{{T "deploy.megjelenites"}}</button>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
@@ -534,13 +526,13 @@
|
|||||||
|
|
||||||
{{if .UserFields}}
|
{{if .UserFields}}
|
||||||
<div class="form-section">
|
<div class="form-section">
|
||||||
<h4>Beállítások</h4>
|
<h4>{{T "deploy.beallitasok"}}</h4>
|
||||||
{{range .UserFields}}
|
{{range .UserFields}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="field-{{.EnvVar}}">
|
<label for="field-{{.EnvVar}}">
|
||||||
{{.Label}}
|
{{.Label}}
|
||||||
{{if or .Required (eq .Type "password")}}<span class="required">*</span>{{end}}
|
{{if or .Required (eq .Type "password")}}<span class="required">*</span>{{end}}
|
||||||
{{if .LockedAfterDeploy}}<span class="locked-hint">telepítés után nem módosítható</span>{{end}}
|
{{if .LockedAfterDeploy}}<span class="locked-hint">{{T "deploy.telepites_utan_nem_modosithato"}}</span>{{end}}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
{{if eq .Type "subdomain"}}
|
{{if eq .Type "subdomain"}}
|
||||||
@@ -550,7 +542,7 @@
|
|||||||
{{/* R-351: a reinstall offers the address the customer's own backup recorded,
|
{{/* R-351: a reinstall offers the address the customer's own backup recorded,
|
||||||
ahead of the catalog default. Editable — a domain can legitimately change. */}}
|
ahead of the catalog default. Editable — a domain can legitimately change. */}}
|
||||||
value="{{if and $.AlreadyDeployed $.DeployedFieldValues}}{{index $.DeployedFieldValues .EnvVar}}{{else if index $.RestoreFieldValues .EnvVar}}{{index $.RestoreFieldValues .EnvVar}}{{else}}{{.Default}}{{end}}"
|
value="{{if and $.AlreadyDeployed $.DeployedFieldValues}}{{index $.DeployedFieldValues .EnvVar}}{{else if index $.RestoreFieldValues .EnvVar}}{{index $.RestoreFieldValues .EnvVar}}{{else}}{{.Default}}{{end}}"
|
||||||
placeholder="aldomain"
|
placeholder="{{T "deploy.aldomain_placeholder"}}"
|
||||||
pattern="[a-z0-9]([a-z0-9-]*[a-z0-9])?"
|
pattern="[a-z0-9]([a-z0-9-]*[a-z0-9])?"
|
||||||
required
|
required
|
||||||
{{if $.AlreadyDeployed}}disabled{{end}}
|
{{if $.AlreadyDeployed}}disabled{{end}}
|
||||||
@@ -558,7 +550,7 @@
|
|||||||
<span class="subdomain-suffix">.{{$.Domain}}</span>
|
<span class="subdomain-suffix">.{{$.Domain}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{if not $.AlreadyDeployed}}
|
{{if not $.AlreadyDeployed}}
|
||||||
<span class="form-hint">Az aldomain telepítés után nem módosítható. Megváltoztatáshoz az alkalmazás eltávolítása és újratelepítése szükséges (minden adat törlődik).</span>
|
<span class="form-hint">{{T "deploy.az_aldomain_telepites_utan_nem"}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else if eq .Type "select"}}
|
{{else if eq .Type "select"}}
|
||||||
<select id="field-{{.EnvVar}}" name="{{.EnvVar}}" class="form-control"
|
<select id="field-{{.EnvVar}}" name="{{.EnvVar}}" class="form-control"
|
||||||
@@ -577,18 +569,18 @@
|
|||||||
{{if $.AlreadyDeployed}}disabled{{end}}>
|
{{if $.AlreadyDeployed}}disabled{{end}}>
|
||||||
<button type="button" class="btn btn-sm btn-outline pw-toggle-btn"
|
<button type="button" class="btn btn-sm btn-outline pw-toggle-btn"
|
||||||
onclick="togglePasswordField('field-{{.EnvVar}}', 'field-confirm-{{.EnvVar}}', this)"
|
onclick="togglePasswordField('field-{{.EnvVar}}', 'field-confirm-{{.EnvVar}}', this)"
|
||||||
title="Megjelenítés">👁</button>
|
title="{{T "deploy.megjelenites"}}">👁</button>
|
||||||
{{if not $.AlreadyDeployed}}
|
{{if not $.AlreadyDeployed}}
|
||||||
<button type="button" class="btn btn-sm btn-outline"
|
<button type="button" class="btn btn-sm btn-outline"
|
||||||
onclick="generatePassword('field-{{.EnvVar}}', 'field-confirm-{{.EnvVar}}')">Generálás</button>
|
onclick="generatePassword('field-{{.EnvVar}}', 'field-confirm-{{.EnvVar}}')">{{T "deploy.generalas"}}</button>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{if $.AlreadyDeployed}}
|
{{if $.AlreadyDeployed}}
|
||||||
<span class="form-hint">Telepítéskor beállított kezdeti jelszó — ha az alkalmazásban megváltoztattad, az itt nem frissül.</span>
|
<span class="form-hint">{{T "deploy.telepiteskor_beallitott_kezdeti_jelszo_h"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="input-with-button" style="margin-top:.25rem">
|
<div class="input-with-button" style="margin-top:.25rem">
|
||||||
<input type="password" id="field-confirm-{{.EnvVar}}"
|
<input type="password" id="field-confirm-{{.EnvVar}}"
|
||||||
class="form-control" placeholder="Jelszó megerősítése"
|
class="form-control" placeholder="{{T "deploy.jelszo_megerositese"}}"
|
||||||
data-confirm-for="field-{{.EnvVar}}">
|
data-confirm-for="field-{{.EnvVar}}">
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -596,7 +588,7 @@
|
|||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" id="field-{{.EnvVar}}" name="{{.EnvVar}}" value="true"
|
<input type="checkbox" id="field-{{.EnvVar}}" name="{{.EnvVar}}" value="true"
|
||||||
{{if $.AlreadyDeployed}}disabled{{end}}>
|
{{if $.AlreadyDeployed}}disabled{{end}}>
|
||||||
<span class="toggle-label">Igen</span>
|
<span class="toggle-label">{{T "deploy.igen"}}</span>
|
||||||
</label>
|
</label>
|
||||||
{{else if eq .Type "path"}}
|
{{else if eq .Type "path"}}
|
||||||
{{if $.StoragePaths}}
|
{{if $.StoragePaths}}
|
||||||
@@ -611,19 +603,18 @@
|
|||||||
restoring into a different drive is the mismatch the restore then has
|
restoring into a different drive is the mismatch the restore then has
|
||||||
to stop and name. The customer can still pick another. */}}
|
to stop and name. The customer can still pick another. */}}
|
||||||
{{if $.AlreadyDeployed}}{{if eq .Path $.CurrentHDDPath}}selected{{end}}{{else if $.RestorePrefillHDDPath}}{{if and (eq .Path $.RestorePrefillHDDPath) (not .NotAllowed)}}selected{{end}}{{else if and .IsDefault (not .NotAllowed)}}selected{{end}}>
|
{{if $.AlreadyDeployed}}{{if eq .Path $.CurrentHDDPath}}selected{{end}}{{else if $.RestorePrefillHDDPath}}{{if and (eq .Path $.RestorePrefillHDDPath) (not .NotAllowed)}}selected{{end}}{{else if and .IsDefault (not .NotAllowed)}}selected{{end}}>
|
||||||
{{.Label}} — {{.FreeHuman}} szabad{{if .NotAllowed}} ({{.NotAllowedNote}}){{else if .IsDefault}} (alapértelmezett){{end}}
|
{{T "deploy.szabad_2"}}{{if .NotAllowed}} ({{.NotAllowedNote}}){{else if .IsDefault}} {{T "deploy.alapertelmezett"}}{{end}}
|
||||||
</option>
|
</option>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if $.CurrentHDDPathMissing}}
|
{{if $.CurrentHDDPathMissing}}
|
||||||
<option value="{{$.CurrentHDDPath}}" selected disabled>{{$.CurrentHDDPath}} (nem elérhető)</option>
|
<option value="{{$.CurrentHDDPath}}" selected disabled>{{T "deploy.nem_elerheto"}}</option>
|
||||||
{{end}}
|
{{end}}
|
||||||
</select>
|
</select>
|
||||||
<div id="storage-space-warn" class="form-hint" style="color:var(--warn);display:none">
|
<div id="storage-space-warn" class="form-hint" style="color:var(--warn);display:none">
|
||||||
<svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> A kiválasztott tárhely majdnem megtelt.
|
<svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> {{T "deploy.a_kivalasztott_tarhely_majdnem_megtelt"}}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-hint" style="margin-top:.4rem;opacity:.8">
|
<div class="form-hint" style="margin-top:.4rem;opacity:.8">
|
||||||
<svg class="ico ico-sm"><use href="#i-info"/></svg> A kiválasztott meghajtón az alkalmazás <strong>fájljai</strong> (média, dokumentumok) tárolódnak.
|
<svg class="ico ico-sm"><use href="#i-info"/></svg> {{T "deploy.a_kivalasztott_meghajton_az_alkalmazas"}}
|
||||||
Az <strong>adatbázis a gyors belső SSD-n</strong> fut — és az alkalmazással együtt készül róla biztonsági mentés.
|
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<input type="text" id="field-{{.EnvVar}}" name="{{.EnvVar}}"
|
<input type="text" id="field-{{.EnvVar}}" name="{{.EnvVar}}"
|
||||||
@@ -631,7 +622,7 @@
|
|||||||
placeholder="{{.Placeholder}}"
|
placeholder="{{.Placeholder}}"
|
||||||
{{if .Required}}required{{end}}
|
{{if .Required}}required{{end}}
|
||||||
{{if $.AlreadyDeployed}}disabled{{end}}>
|
{{if $.AlreadyDeployed}}disabled{{end}}>
|
||||||
<span class="form-hint" style="color:var(--warn)">Nincs regisztrált adattároló — adja meg kézzel az útvonalat</span>
|
<span class="form-hint" style="color:var(--warn)">{{T "deploy.nincs_regisztralt_adattarolo_adja_meg"}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<input type="text" id="field-{{.EnvVar}}" name="{{.EnvVar}}"
|
<input type="text" id="field-{{.EnvVar}}" name="{{.EnvVar}}"
|
||||||
@@ -651,26 +642,26 @@
|
|||||||
|
|
||||||
{{if not .AlreadyDeployed}}
|
{{if not .AlreadyDeployed}}
|
||||||
<div class="deploy-actions">
|
<div class="deploy-actions">
|
||||||
<button type="submit" class="btn btn-primary btn-lg"{{if .DockerBelowReserve}} disabled title="Nincs elég szabad tárhely"{{else if and .MemoryInfo (index .MemoryInfo "Blocked")}} disabled title="Nincs elég memória"{{end}}>Telepítés indítása</button>
|
<button type="submit" class="btn btn-primary btn-lg"{{if .DockerBelowReserve}} disabled title="{{T "deploy.nincs_eleg_szabad_tarhely"}}"{{else if and .MemoryInfo (index .MemoryInfo "Blocked")}} disabled title="{{T "deploy.nincs_eleg_memoria"}}"{{end}}>{{T "deploy.telepites_inditasa"}}</button>
|
||||||
<a href="/stacks" class="btn btn-outline">Mégsem</a>
|
<a href="/stacks" class="btn btn-outline">{{T "common.megsem"}}</a>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div id="deploy-progress" class="deploy-progress" style="display:none">
|
<div id="deploy-progress" class="deploy-progress" style="display:none">
|
||||||
<h3>Telepítés folyamatban...</h3>
|
<h3>{{T "deploy.telepites_folyamatban"}}</h3>
|
||||||
<div class="deploy-steps">
|
<div class="deploy-steps">
|
||||||
<div class="deploy-step active" id="step-config">
|
<div class="deploy-step active" id="step-config">
|
||||||
<span class="step-icon"><svg class="ico"><use href="#i-rotate-cw"/></svg></span>
|
<span class="step-icon"><svg class="ico"><use href="#i-rotate-cw"/></svg></span>
|
||||||
<span class="step-text">Konfiguráció mentése...</span>
|
<span class="step-text">{{T "deploy.konfiguracio_mentese"}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="deploy-step" id="step-containers">
|
<div class="deploy-step" id="step-containers">
|
||||||
<span class="step-icon"><svg class="ico"><use href="#i-rotate-cw"/></svg></span>
|
<span class="step-icon"><svg class="ico"><use href="#i-rotate-cw"/></svg></span>
|
||||||
<span class="step-text">Konténer(ek) indítása...</span>
|
<span class="step-text">{{T "deploy.kontener_ek_inditasa"}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="deploy-step" id="step-health">
|
<div class="deploy-step" id="step-health">
|
||||||
<span class="step-icon"><svg class="ico"><use href="#i-rotate-cw"/></svg></span>
|
<span class="step-icon"><svg class="ico"><use href="#i-rotate-cw"/></svg></span>
|
||||||
<span class="step-text">Alkalmazás inicializálása...</span>
|
<span class="step-text">{{T "deploy.alkalmazas_inicializalasa"}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="deploy-warning" class="alert alert-warning" style="display:none"></div>
|
<div id="deploy-warning" class="alert alert-warning" style="display:none"></div>
|
||||||
@@ -701,13 +692,13 @@ function buildPostDeployCard(stackName) {
|
|||||||
if (subdomain && postDeployInfo.domain) {
|
if (subdomain && postDeployInfo.domain) {
|
||||||
var appURL = 'https://' + subdomain + '.' + postDeployInfo.domain;
|
var appURL = 'https://' + subdomain + '.' + postDeployInfo.domain;
|
||||||
html += '<div style="text-align:center;margin:1.5rem 0">' +
|
html += '<div style="text-align:center;margin:1.5rem 0">' +
|
||||||
'<a href="' + appURL + '" target="_blank" class="btn btn-primary btn-lg">Alkalmazás megnyitása ↗</a>' +
|
'<a href="' + appURL + '" target="_blank" class="btn btn-primary btn-lg">{{T "deploy.alkalmazas_megnyitasa"}}</a>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// First steps — with dynamic credential hint
|
// First steps — with dynamic credential hint
|
||||||
if (postDeployInfo.firstSteps && postDeployInfo.firstSteps.length > 0) {
|
if (postDeployInfo.firstSteps && postDeployInfo.firstSteps.length > 0) {
|
||||||
html += '<div class="app-info-card" style="margin-top:1rem"><h4>Első lépések</h4><ol class="app-info-list">';
|
html += '<div class="app-info-card" style="margin-top:1rem"><h4>{{T "deploy.elso_lepesek"}}</h4><ol class="app-info-list">';
|
||||||
for (var i = 0; i < postDeployInfo.firstSteps.length; i++) {
|
for (var i = 0; i < postDeployInfo.firstSteps.length; i++) {
|
||||||
var step = postDeployInfo.firstSteps[i].replace(/DOMAIN/g, postDeployInfo.domain);
|
var step = postDeployInfo.firstSteps[i].replace(/DOMAIN/g, postDeployInfo.domain);
|
||||||
html += '<li>' + step + '</li>';
|
html += '<li>' + step + '</li>';
|
||||||
@@ -742,8 +733,8 @@ function buildPostDeployCard(stackName) {
|
|||||||
credRows += '<tr><td style="padding:.25rem .75rem .25rem 0;color:var(--text-3);white-space:nowrap">' + f.label + '</td>' +
|
credRows += '<tr><td style="padding:.25rem .75rem .25rem 0;color:var(--text-3);white-space:nowrap">' + f.label + '</td>' +
|
||||||
'<td style="padding:.25rem 0;display:flex;align-items:center;gap:.5rem">' +
|
'<td style="padding:.25rem 0;display:flex;align-items:center;gap:.5rem">' +
|
||||||
'<code id="' + credId + '" style="font-family:var(--font-data);letter-spacing:1px">••••••••••••</code>' +
|
'<code id="' + credId + '" style="font-family:var(--font-data);letter-spacing:1px">••••••••••••</code>' +
|
||||||
'<button type="button" class="btn btn-sm btn-outline" onclick="togglePostDeployCred(this,\'' + credId + '\',\'' + val.replace(/'/g, "\\'") + '\')" style="padding:.15rem .4rem;font-size:.75rem">Megjelenítés</button>' +
|
'<button type="button" class="btn btn-sm btn-outline" onclick="togglePostDeployCred(this,\'' + credId + '\',\'' + val.replace(/'/g, "\\'") + '\')" style="padding:.15rem .4rem;font-size:.75rem">{{T "deploy.megjelenites"}}</button>' +
|
||||||
'<button type="button" class="btn btn-sm btn-outline" onclick="copyPostDeployCred(this,\'' + val.replace(/'/g, "\\'") + '\')" style="padding:.15rem .4rem;font-size:.75rem">Másolás</button>' +
|
'<button type="button" class="btn btn-sm btn-outline" onclick="copyPostDeployCred(this,\'' + val.replace(/'/g, "\\'") + '\')" style="padding:.15rem .4rem;font-size:.75rem">{{T "deploy.masolas"}}</button>' +
|
||||||
'</td></tr>';
|
'</td></tr>';
|
||||||
} else {
|
} else {
|
||||||
credRows += '<tr><td style="padding:.25rem .75rem .25rem 0;color:var(--text-3);white-space:nowrap">' + f.label + '</td>' +
|
credRows += '<tr><td style="padding:.25rem .75rem .25rem 0;color:var(--text-3);white-space:nowrap">' + f.label + '</td>' +
|
||||||
@@ -752,23 +743,23 @@ function buildPostDeployCard(stackName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (credRows) {
|
if (credRows) {
|
||||||
html += '<div class="app-info-card" style="margin-top:1rem"><h4>Bejelentkezés</h4>' +
|
html += '<div class="app-info-card" style="margin-top:1rem"><h4>{{T "deploy.bejelentkezes"}}</h4>' +
|
||||||
'<table style="margin:.5rem 0">' + credRows + '</table></div>';
|
'<table style="margin:.5rem 0">' + credRows + '</table></div>';
|
||||||
} else if (postDeployInfo.defaultCreds) {
|
} else if (postDeployInfo.defaultCreds) {
|
||||||
var creds = postDeployInfo.defaultCreds.replace(/DOMAIN/g, postDeployInfo.domain);
|
var creds = postDeployInfo.defaultCreds.replace(/DOMAIN/g, postDeployInfo.domain);
|
||||||
html += '<div class="app-info-card" style="margin-top:1rem"><h4>Bejelentkezés</h4>' +
|
html += '<div class="app-info-card" style="margin-top:1rem"><h4>{{T "deploy.bejelentkezes"}}</h4>' +
|
||||||
'<p class="app-info-creds">' + creds + '</p></div>';
|
'<p class="app-info-creds">' + creds + '</p></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Docs link
|
// Docs link
|
||||||
if (postDeployInfo.docsURL) {
|
if (postDeployInfo.docsURL) {
|
||||||
html += '<div style="margin-top:1rem"><a href="' + postDeployInfo.docsURL + '" target="_blank" class="btn btn-sm btn-outline">Dokumentáció ↗</a></div>';
|
html += '<div style="margin-top:1rem"><a href="' + postDeployInfo.docsURL + '" target="_blank" class="btn btn-sm btn-outline">{{T "deploy.dokumentacio"}}</a></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action buttons
|
// Action buttons
|
||||||
html += '<div style="display:flex;gap:.75rem;margin-top:1.5rem;flex-wrap:wrap">' +
|
html += '<div style="display:flex;gap:.75rem;margin-top:1.5rem;flex-wrap:wrap">' +
|
||||||
'<a href="/stacks/' + stackName + '/deploy" class="btn btn-outline">Beállítások és jelszavak megtekintése</a>' +
|
'<a href="/stacks/' + stackName + '/deploy" class="btn btn-outline">{{T "deploy.beallitasok_es_jelszavak_megtekintese"}}</a>' +
|
||||||
'<a href="/stacks" class="btn btn-sm btn-outline">← Alkalmazások</a>' +
|
'<a href="/stacks" class="btn btn-sm btn-outline">{{T "deploy.alkalmazasok"}}</a>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
@@ -796,7 +787,7 @@ function revealAutoField(stackName, envVar, btn) {
|
|||||||
el.value = '';
|
el.value = '';
|
||||||
el.type = 'password';
|
el.type = 'password';
|
||||||
btn.dataset.shown = '';
|
btn.dataset.shown = '';
|
||||||
btn.textContent = 'Megjelenítés';
|
btn.textContent = '{{T "deploy.megjelenites"}}';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
@@ -807,18 +798,18 @@ function revealAutoField(stackName, envVar, btn) {
|
|||||||
body: 'env_var=' + encodeURIComponent(envVar)
|
body: 'env_var=' + encodeURIComponent(envVar)
|
||||||
}).then(function (r) { return r.json(); }).then(function (j) {
|
}).then(function (r) { return r.json(); }).then(function (j) {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
|
if (!j.ok) { showAlert(j.error || '{{T "deploy.a_lekeres_nem_sikerult"}}'); return; }
|
||||||
el.value = j.data.value;
|
el.value = j.data.value;
|
||||||
el.type = 'text';
|
el.type = 'text';
|
||||||
btn.dataset.shown = '1';
|
btn.dataset.shown = '1';
|
||||||
btn.textContent = 'Elrejtés';
|
btn.textContent = '{{T "deploy.elrejtes"}}';
|
||||||
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
|
}).catch(function () { btn.disabled = false; showAlert('{{T "deploy.a_lekeres_nem_sikerult"}}'); });
|
||||||
}
|
}
|
||||||
function toggleAutoField(fieldId, btn) {
|
function toggleAutoField(fieldId, btn) {
|
||||||
var el = document.getElementById(fieldId);
|
var el = document.getElementById(fieldId);
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
el.type = el.type === 'password' ? 'text' : 'password';
|
el.type = el.type === 'password' ? 'text' : 'password';
|
||||||
btn.textContent = el.type === 'password' ? 'Megjelenítés' : 'Elrejtés';
|
btn.textContent = el.type === 'password' ? '{{T "deploy.megjelenites"}}' : '{{T "deploy.elrejtes"}}';
|
||||||
}
|
}
|
||||||
function generatePassword(fieldId, confirmFieldId) {
|
function generatePassword(fieldId, confirmFieldId) {
|
||||||
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||||
@@ -841,7 +832,7 @@ function togglePasswordField(fieldId, confirmFieldId, btn) {
|
|||||||
el.type = newType;
|
el.type = newType;
|
||||||
var ce = document.getElementById(confirmFieldId);
|
var ce = document.getElementById(confirmFieldId);
|
||||||
if (ce) ce.type = newType;
|
if (ce) ce.type = newType;
|
||||||
btn.title = newType === 'password' ? 'Megjelenítés' : 'Elrejtés';
|
btn.title = newType === 'password' ? '{{T "deploy.megjelenites"}}' : '{{T "deploy.elrejtes"}}';
|
||||||
}
|
}
|
||||||
|
|
||||||
function togglePostDeployCred(btn, credId, val) {
|
function togglePostDeployCred(btn, credId, val) {
|
||||||
@@ -849,17 +840,17 @@ function togglePostDeployCred(btn, credId, val) {
|
|||||||
if (!el) return;
|
if (!el) return;
|
||||||
if (el.textContent === val) {
|
if (el.textContent === val) {
|
||||||
el.textContent = '••••••••••••';
|
el.textContent = '••••••••••••';
|
||||||
btn.textContent = 'Megjelenítés';
|
btn.textContent = '{{T "deploy.megjelenites"}}';
|
||||||
} else {
|
} else {
|
||||||
el.textContent = val;
|
el.textContent = val;
|
||||||
btn.textContent = 'Elrejtés';
|
btn.textContent = '{{T "deploy.elrejtes"}}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function copyPostDeployCred(btn, val) {
|
function copyPostDeployCred(btn, val) {
|
||||||
if (navigator.clipboard) {
|
if (navigator.clipboard) {
|
||||||
navigator.clipboard.writeText(val).then(function() {
|
navigator.clipboard.writeText(val).then(function() {
|
||||||
var orig = btn.textContent;
|
var orig = btn.textContent;
|
||||||
btn.textContent = 'Másolva!';
|
btn.textContent = '{{T "deploy.masolva"}}';
|
||||||
setTimeout(function() { btn.textContent = orig; }, 1500);
|
setTimeout(function() { btn.textContent = orig; }, 1500);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -867,8 +858,8 @@ function copyPostDeployCred(btn, val) {
|
|||||||
|
|
||||||
function deleteStaleData(stackName, stalePath, btn) {
|
function deleteStaleData(stackName, stalePath, btn) {
|
||||||
// Two-step inline confirm (the irreversible delete keeps its double acknowledgement).
|
// Two-step inline confirm (the irreversible delete keeps its double acknowledgement).
|
||||||
felhomConfirm(btn, 'Biztosan törölni szeretnéd a korábbi adatokat? Tárhely: ' + stalePath + ' — FIGYELEM: a művelet visszavonhatatlan! Előtte győződj meg róla, hogy az alkalmazás az új tárolóról megfelelően működik.', function () {
|
felhomConfirm(btn, '{{T "deploy.biztosan_torolni_szeretned_a_korabbi"}} ' + stalePath + ' {{T "deploy.figyelem_a_muvelet_visszavonhatatlan_elo"}}', function () {
|
||||||
felhomConfirm(btn, 'UTOLSÓ FIGYELMEZTETÉS! A törlés visszavonhatatlan. Biztosan folytatod?', function () {
|
felhomConfirm(btn, '{{T "deploy.utolso_figyelmeztetes_a_torles_visszavon"}}', function () {
|
||||||
deleteStaleDataRun(stackName, stalePath, btn);
|
deleteStaleDataRun(stackName, stalePath, btn);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -876,7 +867,7 @@ function deleteStaleData(stackName, stalePath, btn) {
|
|||||||
|
|
||||||
function deleteStaleDataRun(stackName, stalePath, btn) {
|
function deleteStaleDataRun(stackName, stalePath, btn) {
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.textContent = 'Törlés folyamatban...';
|
btn.textContent = '{{T "deploy.torles_folyamatban"}}';
|
||||||
|
|
||||||
fetch('/api/storage/stale-cleanup', {
|
fetch('/api/storage/stale-cleanup', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -886,14 +877,14 @@ function deleteStaleDataRun(stackName, stalePath, btn) {
|
|||||||
.then(function(r) { return r.json(); })
|
.then(function(r) { return r.json(); })
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (!data.ok) {
|
if (!data.ok) {
|
||||||
showAlert('Hiba: ' + (data.error || 'Ismeretlen hiba'));
|
showAlert('{{T "common.hiba_kettospont"}} ' + (data.error || '{{T "deploy.ismeretlen_hiba"}}'));
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = 'Korábbi adatok törlése';
|
btn.textContent = '{{T "deploy.korabbi_adatok_torlese"}}';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var msg = 'Korábbi adatok törölve!\n\nFelszabadított hely: ' + (data.freed_human || '?');
|
var msg = '{{T "deploy.korabbi_adatok_torolve_n_nfelszabaditott"}} ' + (data.freed_human || '?');
|
||||||
if (data.errors && data.errors.length > 0) {
|
if (data.errors && data.errors.length > 0) {
|
||||||
msg += '\n\nNéhány hiba történt:\n' + data.errors.join('\n');
|
msg += '{{T "deploy.n_nnehany_hiba_tortent_n"}}' + data.errors.join('\n');
|
||||||
}
|
}
|
||||||
showAlert(msg);
|
showAlert(msg);
|
||||||
// Remove the stale data card from DOM
|
// Remove the stale data card from DOM
|
||||||
@@ -906,9 +897,9 @@ function deleteStaleDataRun(stackName, stalePath, btn) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function(e) {
|
.catch(function(e) {
|
||||||
showAlert('Hálózati hiba: ' + e.message);
|
showAlert('{{T "deploy.halozati_hiba_2"}} ' + e.message);
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = 'Korábbi adatok törlése';
|
btn.textContent = '{{T "deploy.korabbi_adatok_torlese"}}';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -920,7 +911,7 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
|||||||
for (const pf of passwordFields) {
|
for (const pf of passwordFields) {
|
||||||
if (!pf.disabled && pf.value.trim() === '') {
|
if (!pf.disabled && pf.value.trim() === '') {
|
||||||
const label = pf.closest('.form-group').querySelector('label').textContent.trim();
|
const label = pf.closest('.form-group').querySelector('label').textContent.trim();
|
||||||
showAlert('Kötelező mező: ' + label + '\nHasználja a Generálás gombot vagy írjon be egy jelszót.');
|
showAlert('{{T "deploy.kotelezo_mezo"}} ' + label + '{{T "deploy.nhasznalja_a_generalas_gombot_vagy"}}');
|
||||||
pf.focus();
|
pf.focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -932,7 +923,7 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
|||||||
const mainEl = document.getElementById(ci.getAttribute('data-confirm-for'));
|
const mainEl = document.getElementById(ci.getAttribute('data-confirm-for'));
|
||||||
if (mainEl && !mainEl.disabled && ci.value !== mainEl.value) {
|
if (mainEl && !mainEl.disabled && ci.value !== mainEl.value) {
|
||||||
const label = mainEl.closest('.form-group').querySelector('label').textContent.trim();
|
const label = mainEl.closest('.form-group').querySelector('label').textContent.trim();
|
||||||
showAlert('A két jelszó nem egyezik: ' + label);
|
showAlert('{{T "deploy.a_ket_jelszo_nem_egyezik"}} ' + label);
|
||||||
ci.focus();
|
ci.focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -943,7 +934,7 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
|||||||
if (subdomainField && !subdomainField.disabled) {
|
if (subdomainField && !subdomainField.disabled) {
|
||||||
const sd = subdomainField.value.trim().toLowerCase();
|
const sd = subdomainField.value.trim().toLowerCase();
|
||||||
if (!sd || !/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(sd)) {
|
if (!sd || !/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(sd)) {
|
||||||
showAlert('Az aldomain csak kisbetűket, számokat és kötőjelet tartalmazhat, és nem kezdődhet/végződhet kötőjellel.');
|
showAlert('{{T "deploy.az_aldomain_csak_kisbetuket_szamokat"}}');
|
||||||
subdomainField.focus();
|
subdomainField.focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -954,7 +945,7 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
|||||||
for (const rf of requiredFields) {
|
for (const rf of requiredFields) {
|
||||||
if (!rf.disabled && rf.value.trim() === '') {
|
if (!rf.disabled && rf.value.trim() === '') {
|
||||||
const label = rf.closest('.form-group').querySelector('label').textContent.trim();
|
const label = rf.closest('.form-group').querySelector('label').textContent.trim();
|
||||||
showAlert('Kötelező mező: ' + label);
|
showAlert('{{T "deploy.kotelezo_mezo"}} ' + label);
|
||||||
rf.focus();
|
rf.focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -962,7 +953,7 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
|||||||
|
|
||||||
const btn = e.target.querySelector('[type=submit]');
|
const btn = e.target.querySelector('[type=submit]');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.textContent = 'Telepítés folyamatban...';
|
btn.textContent = '{{T "deploy.telepites_folyamatban"}}';
|
||||||
|
|
||||||
const values = {};
|
const values = {};
|
||||||
const inputs = e.target.querySelectorAll('input, select');
|
const inputs = e.target.querySelectorAll('input, select');
|
||||||
@@ -1005,8 +996,8 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
|||||||
});
|
});
|
||||||
var data = await resp.json();
|
var data = await resp.json();
|
||||||
if (!data.ok) {
|
if (!data.ok) {
|
||||||
showAlert('Hiba: ' + data.error);
|
showAlert('{{T "common.hiba_kettospont"}} ' + data.error);
|
||||||
btn.textContent = 'Telepítés indítása';
|
btn.textContent = '{{T "deploy.telepites_inditasa"}}';
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1014,8 +1005,8 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
|||||||
// Deploy API returned success — switch to progress view
|
// Deploy API returned success — switch to progress view
|
||||||
formEl.style.display = 'none';
|
formEl.style.display = 'none';
|
||||||
progressEl.style.display = 'block';
|
progressEl.style.display = 'block';
|
||||||
setStep(stepConfig, 'done', 'Konfiguráció mentve');
|
setStep(stepConfig, 'done', '{{T "deploy.konfiguracio_mentve"}}');
|
||||||
setStep(stepContainers, 'active', 'Konténer(ek) indítása...');
|
setStep(stepContainers, 'active', '{{T "deploy.kontener_ek_inditasa"}}');
|
||||||
|
|
||||||
if (data.data && data.data.warning) {
|
if (data.data && data.data.warning) {
|
||||||
warningEl.textContent = data.data.warning;
|
warningEl.textContent = data.data.warning;
|
||||||
@@ -1027,13 +1018,13 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
|||||||
var pollTimeout = 120000;
|
var pollTimeout = 120000;
|
||||||
var pollTimer = setInterval(async function() {
|
var pollTimer = setInterval(async function() {
|
||||||
var elapsed = Math.round((Date.now() - startTime) / 1000);
|
var elapsed = Math.round((Date.now() - startTime) / 1000);
|
||||||
elapsedEl.textContent = elapsed + ' másodperce...';
|
elapsedEl.textContent = elapsed + ' {{T "deploy.masodperce"}}';
|
||||||
|
|
||||||
if (Date.now() - startTime > pollTimeout) {
|
if (Date.now() - startTime > pollTimeout) {
|
||||||
clearInterval(pollTimer);
|
clearInterval(pollTimer);
|
||||||
setStep(stepHealth, 'warn', 'Időtúllépés — az alkalmazás még indulhat');
|
setStep(stepHealth, 'warn', '{{T "deploy.idotullepes_az_alkalmazas_meg_indulhat"}}');
|
||||||
resultEl.innerHTML = '<div class="alert alert-warning" style="margin-top:1rem">' +
|
resultEl.innerHTML = '<div class="alert alert-warning" style="margin-top:1rem">' +
|
||||||
'A telepítés időtúllépésbe futott. Az alkalmazás még indulhat.' +
|
'{{T "deploy.a_telepites_idotullepesbe_futott_az"}}' +
|
||||||
'</div>' + buildPostDeployCard(stackName);
|
'</div>' + buildPostDeployCard(stackName);
|
||||||
resultEl.style.display = 'block';
|
resultEl.style.display = 'block';
|
||||||
return;
|
return;
|
||||||
@@ -1049,56 +1040,56 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
|||||||
if (deployError) {
|
if (deployError) {
|
||||||
// Async compose-up failed
|
// Async compose-up failed
|
||||||
clearInterval(pollTimer);
|
clearInterval(pollTimer);
|
||||||
setStep(stepContainers, 'error', 'Telepítés sikertelen');
|
setStep(stepContainers, 'error', '{{T "deploy.telepites_sikertelen"}}');
|
||||||
setStep(stepHealth, 'error');
|
setStep(stepHealth, 'error');
|
||||||
progressEl.querySelector('h3').textContent = 'Telepítés sikertelen';
|
progressEl.querySelector('h3').textContent = '{{T "deploy.telepites_sikertelen"}}';
|
||||||
resultEl.innerHTML = '<div class="alert alert-error" style="margin-top:1rem">' +
|
resultEl.innerHTML = '<div class="alert alert-error" style="margin-top:1rem">' +
|
||||||
'A telepítés nem sikerült: ' + deployError +
|
'{{T "deploy.a_telepites_nem_sikerult"}} ' + deployError +
|
||||||
'</div><a href="/stacks/' + stackName + '/logs" class="btn btn-outline" style="margin-top:.75rem">Naplók megtekintése</a>' +
|
'</div><a href="/stacks/' + stackName + '/logs" class="btn btn-outline" style="margin-top:.75rem">{{T "deploy.naplok_megtekintese"}}</a>' +
|
||||||
' <a href="/stacks" class="btn btn-primary" style="margin-top:.75rem">Alkalmazások</a>';
|
' <a href="/stacks" class="btn btn-primary" style="margin-top:.75rem">{{T "deploy.alkalmazasok_2"}}</a>';
|
||||||
resultEl.style.display = 'block';
|
resultEl.style.display = 'block';
|
||||||
} else if (state === 'deploying') {
|
} else if (state === 'deploying') {
|
||||||
// Compose up in progress (pulling images, creating containers)
|
// Compose up in progress (pulling images, creating containers)
|
||||||
setStep(stepContainers, 'active', 'Képek letöltése, konténerek indítása...');
|
setStep(stepContainers, 'active', '{{T "deploy.kepek_letoltese_kontenerek_inditasa"}}');
|
||||||
} else if (state === 'running') {
|
} else if (state === 'running') {
|
||||||
clearInterval(pollTimer);
|
clearInterval(pollTimer);
|
||||||
setStep(stepContainers, 'done', 'Konténerek elindultak');
|
setStep(stepContainers, 'done', '{{T "deploy.kontenerek_elindultak"}}');
|
||||||
setStep(stepHealth, 'done', 'Alkalmazás kész!');
|
setStep(stepHealth, 'done', '{{T "deploy.alkalmazas_kesz"}}');
|
||||||
progressEl.querySelector('h3').textContent = 'Telepítés sikeres!';
|
progressEl.querySelector('h3').textContent = '{{T "deploy.telepites_sikeres"}}';
|
||||||
resultEl.innerHTML = '<div class="alert alert-info" style="margin-top:1rem">' +
|
resultEl.innerHTML = '<div class="alert alert-info" style="margin-top:1rem">' +
|
||||||
'Az alkalmazás sikeresen telepítve és fut!' +
|
'{{T "deploy.az_alkalmazas_sikeresen_telepitve_es"}}' +
|
||||||
'</div>' + buildPostDeployCard(stackName);
|
'</div>' + buildPostDeployCard(stackName);
|
||||||
resultEl.style.display = 'block';
|
resultEl.style.display = 'block';
|
||||||
} else if (state === 'starting') {
|
} else if (state === 'starting') {
|
||||||
setStep(stepContainers, 'done', 'Konténerek elindultak');
|
setStep(stepContainers, 'done', '{{T "deploy.kontenerek_elindultak"}}');
|
||||||
setStep(stepHealth, 'active', 'Alkalmazás inicializálása...');
|
setStep(stepHealth, 'active', '{{T "deploy.alkalmazas_inicializalasa"}}');
|
||||||
} else if (state === 'unhealthy') {
|
} else if (state === 'unhealthy') {
|
||||||
clearInterval(pollTimer);
|
clearInterval(pollTimer);
|
||||||
setStep(stepContainers, 'done', 'Konténerek elindultak');
|
setStep(stepContainers, 'done', '{{T "deploy.kontenerek_elindultak"}}');
|
||||||
setStep(stepHealth, 'warn', 'Állapotjelző: még inicializál');
|
setStep(stepHealth, 'warn', '{{T "deploy.allapotjelzo_meg_inicializal"}}');
|
||||||
progressEl.querySelector('h3').textContent = 'Telepítés sikeres!';
|
progressEl.querySelector('h3').textContent = '{{T "deploy.telepites_sikeres"}}';
|
||||||
resultEl.innerHTML = '<div class="alert alert-warning" style="margin-top:1rem">' +
|
resultEl.innerHTML = '<div class="alert alert-warning" style="margin-top:1rem">' +
|
||||||
'Az alkalmazás elindult, de még inicializálódik. ' +
|
'{{T "deploy.az_alkalmazas_elindult_de_meg"}} ' +
|
||||||
'Ez normális az első percekben — az alkalmazás már elérhető lehet.' +
|
'{{T "deploy.ez_normalis_az_elso_percekben"}}' +
|
||||||
'</div>' + buildPostDeployCard(stackName);
|
'</div>' + buildPostDeployCard(stackName);
|
||||||
resultEl.style.display = 'block';
|
resultEl.style.display = 'block';
|
||||||
} else if (state === 'exited' || state === 'stopped') {
|
} else if (state === 'exited' || state === 'stopped') {
|
||||||
clearInterval(pollTimer);
|
clearInterval(pollTimer);
|
||||||
setStep(stepContainers, 'error', 'A konténer leállt');
|
setStep(stepContainers, 'error', '{{T "deploy.a_kontener_leallt"}}');
|
||||||
setStep(stepHealth, 'error');
|
setStep(stepHealth, 'error');
|
||||||
progressEl.querySelector('h3').textContent = 'Telepítés sikertelen';
|
progressEl.querySelector('h3').textContent = '{{T "deploy.telepites_sikertelen"}}';
|
||||||
resultEl.innerHTML = '<div class="alert alert-error" style="margin-top:1rem">' +
|
resultEl.innerHTML = '<div class="alert alert-error" style="margin-top:1rem">' +
|
||||||
'A konténer leállt. Ellenőrizze a naplókat.' +
|
'{{T "deploy.a_kontener_leallt_ellenorizze_a"}}' +
|
||||||
'</div><a href="/stacks/' + stackName + '/logs" class="btn btn-outline" style="margin-top:.75rem">Naplók megtekintése</a>' +
|
'</div><a href="/stacks/' + stackName + '/logs" class="btn btn-outline" style="margin-top:.75rem">{{T "deploy.naplok_megtekintese"}}</a>' +
|
||||||
' <a href="/stacks" class="btn btn-primary" style="margin-top:.75rem">Alkalmazások</a>';
|
' <a href="/stacks" class="btn btn-primary" style="margin-top:.75rem">{{T "deploy.alkalmazasok_2"}}</a>';
|
||||||
resultEl.style.display = 'block';
|
resultEl.style.display = 'block';
|
||||||
}
|
}
|
||||||
} catch(pollErr) {}
|
} catch(pollErr) {}
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlert('Hálózati hiba: ' + err.message);
|
showAlert('{{T "deploy.halozati_hiba_2"}} ' + err.message);
|
||||||
btn.textContent = 'Telepítés indítása';
|
btn.textContent = '{{T "deploy.telepites_inditasa"}}';
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="share-field">
|
<div class="share-field">
|
||||||
{{if .SharePasswordSet}}
|
{{if .SharePasswordSet}}
|
||||||
<label class="share-label">{{T "launcher.jelszo"}}</label>
|
<label class="share-label">{{T "common.jelszo"}}</label>
|
||||||
<p class="share-note">{{T "launcher.a_megosztas_jelszoval_vedett"}}</p>
|
<p class="share-note">{{T "launcher.a_megosztas_jelszoval_vedett"}}</p>
|
||||||
<form method="POST" action="/launcher/share/password">
|
<form method="POST" action="/launcher/share/password">
|
||||||
{{.CSRFField}}
|
{{.CSRFField}}
|
||||||
@@ -101,14 +101,14 @@
|
|||||||
<form method="POST" action="/launcher/share/enable">
|
<form method="POST" action="/launcher/share/enable">
|
||||||
{{.CSRFField}}
|
{{.CSRFField}}
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<button type="button" class="btn btn-outline" onclick="closeShareModal()">{{T "launcher.bezaras"}}</button>
|
<button type="button" class="btn btn-outline" onclick="closeShareModal()">{{T "common.bezaras"}}</button>
|
||||||
<button type="submit" class="btn btn-primary">{{T "launcher.megosztas_bekapcsolasa"}}</button>
|
<button type="submit" class="btn btn-primary">{{T "launcher.megosztas_bekapcsolasa"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .ShareEnabled}}
|
{{if .ShareEnabled}}
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<button type="button" class="btn btn-outline" onclick="closeShareModal()">{{T "launcher.bezaras"}}</button>
|
<button type="button" class="btn btn-outline" onclick="closeShareModal()">{{T "common.bezaras"}}</button>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -265,7 +265,7 @@
|
|||||||
});
|
});
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
if (toast) {
|
if (toast) {
|
||||||
toast.textContent = data.ok ? (data.message || '{{T "layout.sablonok_frissitve"}}') : ('{{T "layout.hiba"}} ' + (data.error || '{{T "layout.ismeretlen_hiba"}}'));
|
toast.textContent = data.ok ? (data.message || '{{T "layout.sablonok_frissitve"}}') : ('{{T "common.hiba_kettospont"}} ' + (data.error || '{{T "layout.ismeretlen_hiba"}}'));
|
||||||
toast.className = 'sync-toast ' + (data.ok ? 'sync-toast-ok' : 'sync-toast-err');
|
toast.className = 'sync-toast ' + (data.ok ? 'sync-toast-ok' : 'sync-toast-err');
|
||||||
toast.style.display = 'block';
|
toast.style.display = 'block';
|
||||||
setTimeout(function() { toast.style.display = 'none'; }, 5000);
|
setTimeout(function() { toast.style.display = 'none'; }, 5000);
|
||||||
@@ -298,7 +298,7 @@
|
|||||||
});
|
});
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
if (!data.ok) {
|
if (!data.ok) {
|
||||||
showAlert('{{T "layout.hiba"}} ' + (data.error || '{{T "layout.ismeretlen_hiba"}}'));
|
showAlert('{{T "common.hiba_kettospont"}} ' + (data.error || '{{T "layout.ismeretlen_hiba"}}'));
|
||||||
btn.textContent = origText;
|
btn.textContent = origText;
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.classList.remove('loading');
|
btn.classList.remove('loading');
|
||||||
@@ -358,13 +358,13 @@
|
|||||||
'<div class="alert alert-warning" style="margin-bottom:.75rem">{{T "layout.ez_a_muvelet_nem_visszavonhato"}}</div>' +
|
'<div class="alert alert-warning" style="margin-bottom:.75rem">{{T "layout.ez_a_muvelet_nem_visszavonhato"}}</div>' +
|
||||||
hddInfo + checkboxHTML +
|
hddInfo + checkboxHTML +
|
||||||
'<div class="modal-actions">' +
|
'<div class="modal-actions">' +
|
||||||
'<button class="btn btn-outline" onclick="closeDeleteModal()">{{T "layout.megsem"}}</button>' +
|
'<button class="btn btn-outline" onclick="closeDeleteModal()">{{T "common.megsem"}}</button>' +
|
||||||
'<button class="btn btn-danger" id="confirm-delete-btn" onclick="confirmDelete(\'' + name + '\')">{{T "layout.torles"}}</button>' +
|
'<button class="btn btn-danger" id="confirm-delete-btn" onclick="confirmDelete(\'' + name + '\')">{{T "common.torles"}}</button>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
modal.querySelector('.modal-card').innerHTML =
|
modal.querySelector('.modal-card').innerHTML =
|
||||||
'<h3>{{T "layout.hiba_2"}}</h3><p style="color:var(--text-2)">{{T "layout.nem_sikerult_lekerni_az_adatokat"}} ' + err.message + '</p>' +
|
'<h3>{{T "common.hiba"}}</h3><p style="color:var(--text-2)">{{T "layout.nem_sikerult_lekerni_az_adatokat"}} ' + err.message + '</p>' +
|
||||||
'<div class="modal-actions"><button class="btn btn-outline" onclick="closeDeleteModal()">{{T "layout.bezaras"}}</button></div>';
|
'<div class="modal-actions"><button class="btn btn-outline" onclick="closeDeleteModal()">{{T "common.bezaras"}}</button></div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function closeDeleteModal() {
|
function closeDeleteModal() {
|
||||||
@@ -401,16 +401,16 @@
|
|||||||
'<h3>{{T "layout.sikeresen_torolve"}}</h3>' +
|
'<h3>{{T "layout.sikeresen_torolve"}}</h3>' +
|
||||||
'<p style="color:var(--text-2)">{{T "layout.az_alkalmazas"}}' + name + '{{T "layout.torolve_lett"}}</p>' +
|
'<p style="color:var(--text-2)">{{T "layout.az_alkalmazas"}}' + name + '{{T "layout.torolve_lett"}}</p>' +
|
||||||
removedInfo + preservedInfo +
|
removedInfo + preservedInfo +
|
||||||
'<div class="modal-actions"><button class="btn btn-primary" onclick="window.location.href=\'/stacks\'">{{T "layout.bezaras"}}</button></div>';
|
'<div class="modal-actions"><button class="btn btn-primary" onclick="window.location.href=\'/stacks\'">{{T "common.bezaras"}}</button></div>';
|
||||||
} else {
|
} else {
|
||||||
showAlert('{{T "layout.hiba"}} ' + (data.error || '{{T "layout.ismeretlen_hiba"}}'));
|
showAlert('{{T "common.hiba_kettospont"}} ' + (data.error || '{{T "layout.ismeretlen_hiba"}}'));
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = '{{T "layout.torles"}}';
|
btn.textContent = '{{T "common.torles"}}';
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlert('{{T "layout.halozati_hiba"}} ' + err.message);
|
showAlert('{{T "layout.halozati_hiba"}} ' + err.message);
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = '{{T "layout.torles"}}';
|
btn.textContent = '{{T "common.torles"}}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function removeStack(name) {
|
async function removeStack(name) {
|
||||||
@@ -471,13 +471,13 @@
|
|||||||
'<div class="alert alert-warning" style="margin-bottom:.75rem">{{T "layout.ez_a_muvelet_nem_visszavonhato"}}</div>' +
|
'<div class="alert alert-warning" style="margin-bottom:.75rem">{{T "layout.ez_a_muvelet_nem_visszavonhato"}}</div>' +
|
||||||
sections +
|
sections +
|
||||||
'<div class="modal-actions">' +
|
'<div class="modal-actions">' +
|
||||||
'<button class="btn btn-outline" onclick="closeRemoveModal()">{{T "layout.megsem"}}</button>' +
|
'<button class="btn btn-outline" onclick="closeRemoveModal()">{{T "common.megsem"}}</button>' +
|
||||||
'<button class="btn btn-danger" id="confirm-remove-btn" onclick="confirmRemoveStack(\'' + name + '\')">{{T "layout.eltavolitas"}}</button>' +
|
'<button class="btn btn-danger" id="confirm-remove-btn" onclick="confirmRemoveStack(\'' + name + '\')">{{T "common.eltavolitas"}}</button>' +
|
||||||
'</div>' + hddCheckbox;
|
'</div>' + hddCheckbox;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
modal.querySelector('.modal-card').innerHTML =
|
modal.querySelector('.modal-card').innerHTML =
|
||||||
'<h3>{{T "layout.hiba_2"}}</h3><p style="color:var(--text-2)">{{T "layout.nem_sikerult_lekerni_az_adatokat"}} ' + err.message + '</p>' +
|
'<h3>{{T "common.hiba"}}</h3><p style="color:var(--text-2)">{{T "layout.nem_sikerult_lekerni_az_adatokat"}} ' + err.message + '</p>' +
|
||||||
'<div class="modal-actions"><button class="btn btn-outline" onclick="closeRemoveModal()">{{T "layout.bezaras"}}</button></div>';
|
'<div class="modal-actions"><button class="btn btn-outline" onclick="closeRemoveModal()">{{T "common.bezaras"}}</button></div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function closeRemoveModal() {
|
function closeRemoveModal() {
|
||||||
@@ -522,16 +522,16 @@
|
|||||||
'<h3>{{T "layout.sikeresen_eltavolitva"}}</h3>' +
|
'<h3>{{T "layout.sikeresen_eltavolitva"}}</h3>' +
|
||||||
'<p style="color:var(--text-2)">{{T "layout.az_alkalmazas"}}' + name + '{{T "layout.eltavolitva_ujratelepitheto_a_telepites"}}</p>' +
|
'<p style="color:var(--text-2)">{{T "layout.az_alkalmazas"}}' + name + '{{T "layout.eltavolitva_ujratelepitheto_a_telepites"}}</p>' +
|
||||||
removedInfo + preservedInfo +
|
removedInfo + preservedInfo +
|
||||||
'<div class="modal-actions"><button class="btn btn-primary" onclick="window.location.href=\'/stacks\'">{{T "layout.bezaras"}}</button></div>';
|
'<div class="modal-actions"><button class="btn btn-primary" onclick="window.location.href=\'/stacks\'">{{T "common.bezaras"}}</button></div>';
|
||||||
} else {
|
} else {
|
||||||
showAlert('{{T "layout.hiba"}} ' + (data.error || '{{T "layout.ismeretlen_hiba"}}'));
|
showAlert('{{T "common.hiba_kettospont"}} ' + (data.error || '{{T "layout.ismeretlen_hiba"}}'));
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = '{{T "layout.eltavolitas"}}';
|
btn.textContent = '{{T "common.eltavolitas"}}';
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlert('{{T "layout.halozati_hiba"}} ' + err.message);
|
showAlert('{{T "layout.halozati_hiba"}} ' + err.message);
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = '{{T "layout.eltavolitas"}}';
|
btn.textContent = '{{T "common.eltavolitas"}}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
{{define "logs"}}
|
{{define "logs"}}
|
||||||
{{template "layout_start" .}}
|
{{template "layout_start" .}}
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<a href="/stacks" class="btn btn-sm btn-outline">← Vissza</a>
|
<a href="/stacks" class="btn btn-sm btn-outline">{{T "logs.vissza"}}</a>
|
||||||
<h2>{{.Stack.Meta.DisplayName}} — Naplók</h2>
|
<h2>{{T "logs.naplok"}}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="logs-container" id="logs-container">
|
<div class="logs-container" id="logs-container">
|
||||||
<pre class="logs-output" id="logs-output">{{.Logs}}</pre>
|
<pre class="logs-output" id="logs-output">{{.Logs}}</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="logs-actions">
|
<div class="logs-actions">
|
||||||
<span class="logs-live-indicator" id="live-indicator">
|
<span class="logs-live-indicator" id="live-indicator">
|
||||||
<span class="logs-live-dot"></span> Élő
|
<span class="logs-live-dot"></span> {{T "logs.elo"}}
|
||||||
</span>
|
</span>
|
||||||
<button class="btn btn-outline btn-sm" id="logs-toggle" onclick="toggleLive()">Szüneteltetés</button>
|
<button class="btn btn-outline btn-sm" id="logs-toggle" onclick="toggleLive()">{{T "logs.szuneteltetes"}}</button>
|
||||||
<button class="btn btn-outline btn-sm" onclick="fetchLogs()">Frissítés</button>
|
<button class="btn btn-outline btn-sm" onclick="fetchLogs()">{{T "logs.frissites"}}</button>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
@@ -53,13 +53,13 @@
|
|||||||
if (live) {
|
if (live) {
|
||||||
startPolling();
|
startPolling();
|
||||||
indicator.className = 'logs-live-indicator';
|
indicator.className = 'logs-live-indicator';
|
||||||
indicator.innerHTML = '<span class="logs-live-dot"></span> Élő';
|
indicator.innerHTML = '<span class="logs-live-dot"></span> {{T "logs.elo"}}';
|
||||||
toggleBtn.textContent = 'Szüneteltetés';
|
toggleBtn.textContent = '{{T "logs.szuneteltetes"}}';
|
||||||
} else {
|
} else {
|
||||||
stopPolling();
|
stopPolling();
|
||||||
indicator.className = 'logs-live-indicator logs-live-paused';
|
indicator.className = 'logs-live-indicator logs-live-paused';
|
||||||
indicator.innerHTML = 'Szünetelve';
|
indicator.innerHTML = '{{T "logs.szunetelve"}}';
|
||||||
toggleBtn.textContent = 'Folytatás';
|
toggleBtn.textContent = '{{T "logs.folytatas"}}';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,57 +2,57 @@
|
|||||||
{{template "layout_start" .}}
|
{{template "layout_start" .}}
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>Rendszermonitor</h2>
|
<h2>{{T "monitoring.rendszermonitor"}}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Section 0: Host (Proxmox box) health — slice 9, served by the host agent over the local API.
|
<!-- Section 0: Host (Proxmox box) health — slice 9, served by the host agent over the local API.
|
||||||
The de-privileged controller can't read the host itself; this card shows the real box. -->
|
The de-privileged controller can't read the host itself; this card shows the real box. -->
|
||||||
<div class="monitor-card" id="host-health-card">
|
<div class="monitor-card" id="host-health-card">
|
||||||
<div class="monitor-card-header">
|
<div class="monitor-card-header">
|
||||||
<h3>Szerver állapota (gazdagép)</h3>
|
<h3>{{T "monitoring.szerver_allapota_gazdagep"}}</h3>
|
||||||
<span class="sysinfo-value" id="host-health-updated" style="font-size:.75rem;color:var(--text-3)"></span>
|
<span class="sysinfo-value" id="host-health-updated" style="font-size:.75rem;color:var(--text-3)"></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="host-health-unavailable" class="monitoring-banner monitoring-banner-yellow" style="display:none">
|
<div id="host-health-unavailable" class="monitoring-banner monitoring-banner-yellow" style="display:none">
|
||||||
A gazdagép metrikái jelenleg nem elérhetők.
|
{{T "monitoring.a_gazdagep_metrikai_jelenleg_nem"}}
|
||||||
</div>
|
</div>
|
||||||
<div id="host-health-body" style="display:none">
|
<div id="host-health-body" style="display:none">
|
||||||
<div class="sysinfo-grid">
|
<div class="sysinfo-grid">
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">CPU használat</span>
|
<span class="sysinfo-label">{{T "monitoring.cpu_hasznalat"}}</span>
|
||||||
<span class="sysinfo-value" id="host-cpu">–</span>
|
<span class="sysinfo-value" id="host-cpu">–</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Terhelés (load)</span>
|
<span class="sysinfo-label">{{T "monitoring.terheles_load"}}</span>
|
||||||
<span class="sysinfo-value" id="host-load">–</span>
|
<span class="sysinfo-value" id="host-load">–</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Memória</span>
|
<span class="sysinfo-label">{{T "monitoring.memoria"}}</span>
|
||||||
<span class="sysinfo-value" id="host-mem">–</span>
|
<span class="sysinfo-value" id="host-mem">–</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">CPU hőmérséklet</span>
|
<span class="sysinfo-label">{{T "monitoring.cpu_homerseklet"}}</span>
|
||||||
<span class="sysinfo-value" id="host-temp">–</span>
|
<span class="sysinfo-value" id="host-temp">–</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Üzemidő</span>
|
<span class="sysinfo-label">{{T "monitoring.uzemido"}}</span>
|
||||||
<span class="sysinfo-value" id="host-uptime">–</span>
|
<span class="sysinfo-value" id="host-uptime">–</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h4 style="margin:1rem 0 .5rem">Tárolók kapacitása</h4>
|
<h4 style="margin:1rem 0 .5rem">{{T "monitoring.tarolok_kapacitasa"}}</h4>
|
||||||
<div class="storage-bars" id="host-storage-bars"></div>
|
<div class="storage-bars" id="host-storage-bars"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Section 1: System Overview -->
|
<!-- Section 1: System Overview -->
|
||||||
<div class="monitor-card">
|
<div class="monitor-card">
|
||||||
<h3>Rendszer áttekintés</h3>
|
<h3>{{T "monitoring.rendszer_attekintes"}}</h3>
|
||||||
<div class="sysinfo-grid">
|
<div class="sysinfo-grid">
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Gépnév</span>
|
<span class="sysinfo-label">{{T "monitoring.gepnev"}}</span>
|
||||||
<span class="sysinfo-value" id="sysinfo-hostname">–</span>
|
<span class="sysinfo-value" id="sysinfo-hostname">–</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Operációs rendszer</span>
|
<span class="sysinfo-label">{{T "monitoring.operacios_rendszer"}}</span>
|
||||||
<span class="sysinfo-value" id="sysinfo-os">–</span>
|
<span class="sysinfo-value" id="sysinfo-os">–</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
@@ -60,15 +60,15 @@
|
|||||||
<span class="sysinfo-value" id="sysinfo-kernel">–</span>
|
<span class="sysinfo-value" id="sysinfo-kernel">–</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Processzor</span>
|
<span class="sysinfo-label">{{T "monitoring.processzor"}}</span>
|
||||||
<span class="sysinfo-value" id="sysinfo-cpu">–</span>
|
<span class="sysinfo-value" id="sysinfo-cpu">–</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Üzemidő</span>
|
<span class="sysinfo-label">{{T "monitoring.uzemido"}}</span>
|
||||||
<span class="sysinfo-value" id="sysinfo-uptime">–</span>
|
<span class="sysinfo-value" id="sysinfo-uptime">–</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Indítás</span>
|
<span class="sysinfo-label">{{T "monitoring.inditas"}}</span>
|
||||||
<span class="sysinfo-value" id="sysinfo-boot">–</span>
|
<span class="sysinfo-value" id="sysinfo-boot">–</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -76,12 +76,12 @@
|
|||||||
|
|
||||||
<!-- Section 1.5: Storage (moved here for visibility) -->
|
<!-- Section 1.5: Storage (moved here for visibility) -->
|
||||||
<div class="monitor-card">
|
<div class="monitor-card">
|
||||||
<h3>Tárhely</h3>
|
<h3>{{T "monitoring.tarhely"}}</h3>
|
||||||
<div class="storage-bars">
|
<div class="storage-bars">
|
||||||
{{with .SystemInfo}}
|
{{with .SystemInfo}}
|
||||||
<div class="storage-item meter {{usageColor .DiskPercent}}">
|
<div class="storage-item meter {{usageColor .DiskPercent}}">
|
||||||
<div class="storage-header">
|
<div class="storage-header">
|
||||||
<span class="storage-label">Rendszer (/)</span>
|
<span class="storage-label">{{T "common.rendszer_gyoker"}}</span>
|
||||||
<span class="storage-value">{{fmtGB .DiskUsedGB}} / {{fmtGB .DiskTotalGB}} ({{printf "%.0f" .DiskPercent}}%)</span>
|
<span class="storage-value">{{fmtGB .DiskUsedGB}} / {{fmtGB .DiskTotalGB}} ({{printf "%.0f" .DiskPercent}}%)</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="meter-track">
|
<div class="meter-track">
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
<div class="storage-item meter meter-empty storage-disconnected">
|
<div class="storage-item meter meter-empty storage-disconnected">
|
||||||
<div class="storage-header">
|
<div class="storage-header">
|
||||||
<span class="storage-label">{{.Label}}</span>
|
<span class="storage-label">{{.Label}}</span>
|
||||||
<span class="storage-value">— <span class="state-text-neutral">Leválasztva</span></span>
|
<span class="storage-value">— <span class="state-text-neutral">{{T "common.levalasztva"}}</span></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="meter-track"></div>
|
<div class="meter-track"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -127,15 +127,15 @@
|
|||||||
|
|
||||||
<!-- Section 2: Hub Connection Status -->
|
<!-- Section 2: Hub Connection Status -->
|
||||||
<div class="monitor-card">
|
<div class="monitor-card">
|
||||||
<h3>Hub kapcsolat</h3>
|
<h3>{{T "monitoring.hub_kapcsolat"}}</h3>
|
||||||
{{if .HubEnabled}}
|
{{if .HubEnabled}}
|
||||||
{{if .HubConnected}}
|
{{if .HubConnected}}
|
||||||
<div class="monitoring-banner monitoring-banner-green">
|
<div class="monitoring-banner monitoring-banner-green">
|
||||||
Kapcsolódva — a központi rendszer aktívan figyeli a szervert.
|
{{T "monitoring.kapcsolodva_a_kozponti_rendszer_aktivan"}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="monitoring-banner monitoring-banner-red">
|
<div class="monitoring-banner monitoring-banner-red">
|
||||||
Nem elérhető — a központi rendszer nem kapott friss jelentést.
|
{{T "monitoring.nem_elerheto_a_kozponti_rendszer"}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="sysinfo-grid" style="margin-top: 0.75rem">
|
<div class="sysinfo-grid" style="margin-top: 0.75rem">
|
||||||
@@ -144,25 +144,25 @@
|
|||||||
<span class="sysinfo-value"><code>{{.HubURL}}</code></span>
|
<span class="sysinfo-value"><code>{{.HubURL}}</code></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Ügyfél azonosító</span>
|
<span class="sysinfo-label">{{T "common.ugyfel_azonosito"}}</span>
|
||||||
<span class="sysinfo-value"><code>{{.CustomerID}}</code></span>
|
<span class="sysinfo-value"><code>{{.CustomerID}}</code></span>
|
||||||
</div>
|
</div>
|
||||||
{{if not .HubLastSuccess.IsZero}}
|
{{if not .HubLastSuccess.IsZero}}
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Utolsó sikeres jelentés</span>
|
<span class="sysinfo-label">{{T "monitoring.utolso_sikeres_jelentes"}}</span>
|
||||||
<span class="sysinfo-value">{{.HubLastSuccess | timeAgo}}</span>
|
<span class="sysinfo-value">{{.HubLastSuccess | timeAgo}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .HubLastError}}
|
{{if .HubLastError}}
|
||||||
<div class="sysinfo-row">
|
<div class="sysinfo-row">
|
||||||
<span class="sysinfo-label">Utolsó hiba</span>
|
<span class="sysinfo-label">{{T "monitoring.utolso_hiba"}}</span>
|
||||||
<span class="sysinfo-value"><span class="text-error">{{.HubLastError}}</span></span>
|
<span class="sysinfo-value"><span class="text-error">{{.HubLastError}}</span></span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="monitoring-banner monitoring-banner-yellow">
|
<div class="monitoring-banner monitoring-banner-yellow">
|
||||||
A Hub kapcsolat nincs bekapcsolva — a központi monitoring nem aktív.
|
{{T "monitoring.a_hub_kapcsolat_nincs_bekapcsolva"}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
@@ -170,41 +170,41 @@
|
|||||||
<!-- Section 3: System Metrics Charts -->
|
<!-- Section 3: System Metrics Charts -->
|
||||||
<div class="monitor-card">
|
<div class="monitor-card">
|
||||||
<div class="monitor-card-header">
|
<div class="monitor-card-header">
|
||||||
<h3>Rendszer metrikák</h3>
|
<h3>{{T "monitoring.rendszer_metrikak"}}</h3>
|
||||||
<div class="time-range-bar" id="system-range-bar">
|
<div class="time-range-bar" id="system-range-bar">
|
||||||
<button class="filter-btn active" data-range="1h">1 óra</button>
|
<button class="filter-btn active" data-range="1h">{{T "monitoring.1_ora"}}</button>
|
||||||
<button class="filter-btn" data-range="6h">6 óra</button>
|
<button class="filter-btn" data-range="6h">{{T "monitoring.6_ora"}}</button>
|
||||||
<button class="filter-btn" data-range="24h">24 óra</button>
|
<button class="filter-btn" data-range="24h">{{T "monitoring.24_ora"}}</button>
|
||||||
<button class="filter-btn" data-range="7d">7 nap</button>
|
<button class="filter-btn" data-range="7d">{{T "monitoring.7_nap"}}</button>
|
||||||
<button class="filter-btn" data-range="30d">30 nap</button>
|
<button class="filter-btn" data-range="30d">{{T "monitoring.30_nap"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="charts-grid" id="system-charts">
|
<div class="charts-grid" id="system-charts">
|
||||||
<div class="chart-box">
|
<div class="chart-box">
|
||||||
<div class="chart-title">CPU használat (%)</div>
|
<div class="chart-title">{{T "monitoring.cpu_hasznalat_2"}}</div>
|
||||||
<div class="chart-wrap"><canvas id="chart-cpu"></canvas></div>
|
<div class="chart-wrap"><canvas id="chart-cpu"></canvas></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart-box">
|
<div class="chart-box">
|
||||||
<div class="chart-title">Memória használat (GB)</div>
|
<div class="chart-title">{{T "monitoring.memoria_hasznalat_gb"}}</div>
|
||||||
<div class="chart-wrap"><canvas id="chart-memory"></canvas></div>
|
<div class="chart-wrap"><canvas id="chart-memory"></canvas></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart-box">
|
<div class="chart-box">
|
||||||
<div class="chart-title">Hőmérséklet (°C)</div>
|
<div class="chart-title">{{T "monitoring.homerseklet_c"}}</div>
|
||||||
<div class="chart-wrap"><canvas id="chart-temp"></canvas></div>
|
<div class="chart-wrap"><canvas id="chart-temp"></canvas></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart-box">
|
<div class="chart-box">
|
||||||
<div class="chart-title">Terhelés (Load Average)</div>
|
<div class="chart-title">{{T "monitoring.terheles_load_average"}}</div>
|
||||||
<div class="chart-wrap"><canvas id="chart-load"></canvas></div>
|
<div class="chart-wrap"><canvas id="chart-load"></canvas></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart-empty" id="system-charts-empty" style="display:none">
|
<div class="chart-empty" id="system-charts-empty" style="display:none">
|
||||||
Még nincsenek adatok. A metrikák gyűjtése elindult, az első adatok néhány perc múlva megjelennek.
|
{{T "monitoring.meg_nincsenek_adatok_a_metrikak"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Section 3.5: Memory Distribution Bar -->
|
<!-- Section 3.5: Memory Distribution Bar -->
|
||||||
<div class="monitor-card" id="memory-distribution-card" style="display:none">
|
<div class="monitor-card" id="memory-distribution-card" style="display:none">
|
||||||
<h3>Memória eloszlás</h3>
|
<h3>{{T "monitoring.memoria_eloszlas"}}</h3>
|
||||||
<div id="mem-dist-header" class="memory-dist-header"></div>
|
<div id="mem-dist-header" class="memory-dist-header"></div>
|
||||||
<div class="memory-dist-bar" id="mem-dist-bar"></div>
|
<div class="memory-dist-bar" id="mem-dist-bar"></div>
|
||||||
<div class="memory-bar-legend" id="mem-dist-legend"></div>
|
<div class="memory-bar-legend" id="mem-dist-legend"></div>
|
||||||
@@ -212,19 +212,19 @@
|
|||||||
|
|
||||||
<!-- Section 4: Container Resources -->
|
<!-- Section 4: Container Resources -->
|
||||||
<div class="monitor-card">
|
<div class="monitor-card">
|
||||||
<h3>Alkalmazás erőforrások</h3>
|
<h3>{{T "monitoring.alkalmazas_eroforrasok"}}</h3>
|
||||||
<div class="container-charts-row" id="container-charts">
|
<div class="container-charts-row" id="container-charts">
|
||||||
<div class="chart-box chart-box-half">
|
<div class="chart-box chart-box-half">
|
||||||
<div class="chart-title">CPU használat (%)</div>
|
<div class="chart-title">{{T "monitoring.cpu_hasznalat_2"}}</div>
|
||||||
<div class="chart-wrap chart-wrap-bar"><canvas id="chart-container-cpu"></canvas></div>
|
<div class="chart-wrap chart-wrap-bar"><canvas id="chart-container-cpu"></canvas></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart-box chart-box-half">
|
<div class="chart-box chart-box-half">
|
||||||
<div class="chart-title">Memória használat (MB)</div>
|
<div class="chart-title">{{T "monitoring.memoria_hasznalat_mb"}}</div>
|
||||||
<div class="chart-wrap chart-wrap-bar"><canvas id="chart-container-mem"></canvas></div>
|
<div class="chart-wrap chart-wrap-bar"><canvas id="chart-container-mem"></canvas></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart-empty" id="container-charts-empty" style="display:none">
|
<div class="chart-empty" id="container-charts-empty" style="display:none">
|
||||||
Még nincsenek konténer adatok.
|
{{T "monitoring.meg_nincsenek_kontener_adatok"}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -233,12 +233,12 @@
|
|||||||
<div class="monitor-card-header">
|
<div class="monitor-card-header">
|
||||||
<h3 id="container-detail-title">–</h3>
|
<h3 id="container-detail-title">–</h3>
|
||||||
<div class="time-range-bar" id="container-range-bar">
|
<div class="time-range-bar" id="container-range-bar">
|
||||||
<button class="filter-btn active" data-range="1h">1 óra</button>
|
<button class="filter-btn active" data-range="1h">{{T "monitoring.1_ora"}}</button>
|
||||||
<button class="filter-btn" data-range="6h">6 óra</button>
|
<button class="filter-btn" data-range="6h">{{T "monitoring.6_ora"}}</button>
|
||||||
<button class="filter-btn" data-range="24h">24 óra</button>
|
<button class="filter-btn" data-range="24h">{{T "monitoring.24_ora"}}</button>
|
||||||
<button class="filter-btn" data-range="7d">7 nap</button>
|
<button class="filter-btn" data-range="7d">{{T "monitoring.7_nap"}}</button>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-outline btn-sm" onclick="closeContainerDetail()">Bezárás</button>
|
<button class="btn btn-outline btn-sm" onclick="closeContainerDetail()">{{T "common.bezaras"}}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="charts-grid charts-grid-2">
|
<div class="charts-grid charts-grid-2">
|
||||||
<div class="chart-box">
|
<div class="chart-box">
|
||||||
@@ -246,7 +246,7 @@
|
|||||||
<div class="chart-wrap"><canvas id="chart-detail-cpu"></canvas></div>
|
<div class="chart-wrap"><canvas id="chart-detail-cpu"></canvas></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart-box">
|
<div class="chart-box">
|
||||||
<div class="chart-title">Memória (MB)</div>
|
<div class="chart-title">{{T "monitoring.memoria_mb"}}</div>
|
||||||
<div class="chart-wrap"><canvas id="chart-detail-mem"></canvas></div>
|
<div class="chart-wrap"><canvas id="chart-detail-mem"></canvas></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -588,7 +588,7 @@
|
|||||||
|
|
||||||
function fmtMB(mb) { return mb >= 1024 ? (mb/1024).toFixed(1) + ' GB' : Math.round(mb) + ' MB'; }
|
function fmtMB(mb) { return mb >= 1024 ? (mb/1024).toFixed(1) + ' GB' : Math.round(mb) + ' MB'; }
|
||||||
|
|
||||||
header.textContent = 'Használt: ' + fmtMB(usedMB) + ' / ' + fmtMB(totalMB) + ' (' + Math.round(usedMB/totalMB*100) + '%)';
|
header.textContent = '{{T "monitoring.hasznalt"}} ' + fmtMB(usedMB) + ' / ' + fmtMB(totalMB) + ' (' + Math.round(usedMB/totalMB*100) + '%)';
|
||||||
|
|
||||||
// Sort containers by memory usage descending
|
// Sort containers by memory usage descending
|
||||||
containers.sort(function(a, b) { return (b.mem_usage_mb || 0) - (a.mem_usage_mb || 0); });
|
containers.sort(function(a, b) { return (b.mem_usage_mb || 0) - (a.mem_usage_mb || 0); });
|
||||||
@@ -608,12 +608,12 @@
|
|||||||
// OS / system overhead
|
// OS / system overhead
|
||||||
if (osMB > 10) {
|
if (osMB > 10) {
|
||||||
var osPct = (osMB / totalMB * 100).toFixed(2);
|
var osPct = (osMB / totalMB * 100).toFixed(2);
|
||||||
html += '<div class="memory-bar-segment" style="width:' + osPct + '%;background:var(--text-3);opacity:0.5" title="Rendszer: ' + fmtMB(osMB) + '"></div>';
|
html += '<div class="memory-bar-segment" style="width:' + osPct + '%;background:var(--text-3);opacity:0.5" title="{{T "monitoring.rendszer_title"}} ' + fmtMB(osMB) + '"></div>';
|
||||||
legendHtml += '<div class="memory-legend-item"><span class="memory-legend-dot" style="background:var(--text-3);opacity:0.5"></span>Rendszer (' + fmtMB(osMB) + ')</div>';
|
legendHtml += '<div class="memory-legend-item"><span class="memory-legend-dot" style="background:var(--text-3);opacity:0.5"></span>{{T "monitoring.rendszer_2"}}' + fmtMB(osMB) + ')</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free space legend only
|
// Free space legend only
|
||||||
legendHtml += '<div class="memory-legend-item"><span class="memory-legend-dot" style="background:var(--bg-2);border:1px solid var(--line)"></span>Szabad (' + fmtMB(freeMB) + ')</div>';
|
legendHtml += '<div class="memory-legend-item"><span class="memory-legend-dot" style="background:var(--bg-2);border:1px solid var(--line)"></span>{{T "monitoring.szabad"}}' + fmtMB(freeMB) + ')</div>';
|
||||||
|
|
||||||
bar.innerHTML = html;
|
bar.innerHTML = html;
|
||||||
legend.innerHTML = legendHtml;
|
legend.innerHTML = legendHtml;
|
||||||
@@ -641,7 +641,7 @@
|
|||||||
|
|
||||||
window.showContainerDetail = async function(name) {
|
window.showContainerDetail = async function(name) {
|
||||||
detailContainer = name;
|
detailContainer = name;
|
||||||
document.getElementById('container-detail-title').textContent = name + ' — Erőforrás előzmények';
|
document.getElementById('container-detail-title').textContent = name + ' {{T "monitoring.eroforras_elozmenyek"}}';
|
||||||
document.getElementById('container-detail-panel').style.display = '';
|
document.getElementById('container-detail-panel').style.display = '';
|
||||||
document.getElementById('container-detail-panel').scrollIntoView({behavior: 'smooth'});
|
document.getElementById('container-detail-panel').scrollIntoView({behavior: 'smooth'});
|
||||||
await loadContainerDetail();
|
await loadContainerDetail();
|
||||||
@@ -745,7 +745,7 @@
|
|||||||
var bars = document.getElementById('host-storage-bars');
|
var bars = document.getElementById('host-storage-bars');
|
||||||
var targets = Array.isArray(d.storage_targets) ? d.storage_targets : [];
|
var targets = Array.isArray(d.storage_targets) ? d.storage_targets : [];
|
||||||
if (!targets.length) {
|
if (!targets.length) {
|
||||||
bars.innerHTML = '<div class="sysinfo-value" style="color:var(--text-3)">Nincs tároló adat.</div>';
|
bars.innerHTML = '<div class="sysinfo-value" style="color:var(--text-3)">{{T "monitoring.nincs_tarolo_adat"}}</div>';
|
||||||
} else {
|
} else {
|
||||||
var html = '';
|
var html = '';
|
||||||
targets.forEach(function(t) {
|
targets.forEach(function(t) {
|
||||||
@@ -758,7 +758,7 @@
|
|||||||
if (t.state && t.state !== 'attached') {
|
if (t.state && t.state !== 'attached') {
|
||||||
html += '<div class="storage-item meter meter-empty storage-disconnected">' +
|
html += '<div class="storage-item meter meter-empty storage-disconnected">' +
|
||||||
'<div class="storage-header"><span class="storage-label">' + label + '</span>' +
|
'<div class="storage-header"><span class="storage-label">' + label + '</span>' +
|
||||||
'<span class="storage-value">— <span class="state-text-neutral">Nem elérhető</span></span></div>' +
|
'<span class="storage-value">— <span class="state-text-neutral">{{T "monitoring.nem_elerheto"}}</span></span></div>' +
|
||||||
'<div class="meter-track"></div>' + purposeHtml + '</div>';
|
'<div class="meter-track"></div>' + purposeHtml + '</div>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -770,7 +770,7 @@
|
|||||||
}
|
}
|
||||||
if (t.smart) {
|
if (t.smart) {
|
||||||
if (t.smart.temperature_c != null) extra.push(t.smart.temperature_c + ' °C');
|
if (t.smart.temperature_c != null) extra.push(t.smart.temperature_c + ' °C');
|
||||||
if (t.smart.percentage_used != null) extra.push('kopás: ' + t.smart.percentage_used + '%');
|
if (t.smart.percentage_used != null) extra.push('{{T "monitoring.kopas"}} ' + t.smart.percentage_used + '%');
|
||||||
}
|
}
|
||||||
var extraHtml = extra.length ? ' <span style="color:var(--text-3);font-size:.75rem">· ' + escapeHtml(extra.join(' · ')) + '</span>' : '';
|
var extraHtml = extra.length ? ' <span style="color:var(--text-3);font-size:.75rem">· ' + escapeHtml(extra.join(' · ')) + '</span>' : '';
|
||||||
html += '<div class="storage-item meter ' + usageColorClass(pct) + '">' +
|
html += '<div class="storage-item meter ' + usageColorClass(pct) + '">' +
|
||||||
@@ -786,7 +786,7 @@
|
|||||||
|
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
document.getElementById('host-health-updated').textContent =
|
document.getElementById('host-health-updated').textContent =
|
||||||
'Frissítve: ' + now.toLocaleTimeString('hu-HU', {timeZone: budaTZ, hour: '2-digit', minute: '2-digit', second: '2-digit'});
|
'{{T "monitoring.frissitve"}} ' + now.toLocaleTimeString('hu-HU', {timeZone: budaTZ, hour: '2-digit', minute: '2-digit', second: '2-digit'});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadHostMetrics() {
|
async function loadHostMetrics() {
|
||||||
@@ -835,9 +835,9 @@
|
|||||||
var days = Math.floor(seconds / 86400);
|
var days = Math.floor(seconds / 86400);
|
||||||
var hours = Math.floor((seconds % 86400) / 3600);
|
var hours = Math.floor((seconds % 86400) / 3600);
|
||||||
var minutes = Math.floor((seconds % 3600) / 60);
|
var minutes = Math.floor((seconds % 3600) / 60);
|
||||||
if (days > 0) return days + ' nap, ' + hours + ' óra';
|
if (days > 0) return days + ' {{T "monitoring.nap"}} ' + hours + ' {{T "monitoring.ora"}}';
|
||||||
if (hours > 0) return hours + ' óra, ' + minutes + ' perc';
|
if (hours > 0) return hours + ' {{T "monitoring.ora_2"}} ' + minutes + ' {{T "monitoring.perc"}}';
|
||||||
return minutes + ' perc';
|
return minutes + ' {{T "monitoring.perc"}}';
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================
|
// =============================================
|
||||||
|
|||||||
@@ -2,110 +2,110 @@
|
|||||||
{{template "layout_start" .}}
|
{{template "layout_start" .}}
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>Beállítások — Értesítések</h2>
|
<h2>{{T "settings_notifications.beallitasok_ertesitesek"}}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Section C: Notification Preferences -->
|
<!-- Section C: Notification Preferences -->
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Értesítések</h3>
|
<h3>{{T "settings_notifications.ertesitesek"}}</h3>
|
||||||
{{if .HubEnabled}}
|
{{if .HubEnabled}}
|
||||||
{{if .NotificationSuccess}}<div class="alert alert-info">{{.NotificationSuccess}}</div>{{end}}
|
{{if .NotificationSuccess}}<div class="alert alert-info">{{.NotificationSuccess}}</div>{{end}}
|
||||||
{{if .NotificationError}}<div class="alert alert-error">{{.NotificationError}}</div>{{end}}
|
{{if .NotificationError}}<div class="alert alert-error">{{.NotificationError}}</div>{{end}}
|
||||||
<form method="POST" action="/settings/notifications">
|
<form method="POST" action="/settings/notifications">
|
||||||
{{.CSRFField}}
|
{{.CSRFField}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="notification_email">E-mail cím</label>
|
<label for="notification_email">{{T "settings_notifications.e_mail_cim"}}</label>
|
||||||
<input type="email" id="notification_email" name="notification_email"
|
<input type="email" id="notification_email" name="notification_email"
|
||||||
value="{{with .NotificationPrefs}}{{.Email}}{{end}}"
|
value="{{with .NotificationPrefs}}{{.Email}}{{end}}"
|
||||||
placeholder="pelda@email.hu" class="form-control">
|
placeholder="{{T "settings_notifications.pelda_email"}}" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Hibák és figyelmeztetések:</label>
|
<label>{{T "settings_notifications.hibak_es_figyelmeztetesek"}}</label>
|
||||||
<div class="checkbox-group">
|
<div class="checkbox-group">
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_backup_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "backup_failed"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_backup_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "backup_failed"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Biztonsági mentés sikertelen</span>
|
<span class="toggle-label">{{T "settings_notifications.biztonsagi_mentes_sikertelen"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_db_dump_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "db_dump_failed"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_db_dump_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "db_dump_failed"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Adatbázis mentés sikertelen</span>
|
<span class="toggle-label">{{T "settings_notifications.adatbazis_mentes_sikertelen"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_backup_integrity_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "backup_integrity_failed"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_backup_integrity_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "backup_integrity_failed"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Mentés sérülés észlelve</span>
|
<span class="toggle-label">{{T "settings_notifications.mentes_serules_eszlelve"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_crossdrive_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "crossdrive_failed"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_crossdrive_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "crossdrive_failed"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Másodlagos mentés sikertelen</span>
|
<span class="toggle-label">{{T "settings_notifications.masodlagos_mentes_sikertelen"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_offbox_enlarge_blocked" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "offbox_enlarge_blocked"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_offbox_enlarge_blocked" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "offbox_enlarge_blocked"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Távoli mentés — tárhelykeret-figyelmeztetés</span>
|
<span class="toggle-label">{{T "settings_notifications.tavoli_mentes_tarhelykeret_figyelmeztete"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_disk_warning" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "disk_warning"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_disk_warning" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "disk_warning"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Lemez betelőben (90% felett)</span>
|
<span class="toggle-label">{{T "settings_notifications.lemez_beteloben_90_felett"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_disk_critical" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "disk_critical"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_disk_critical" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "disk_critical"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Lemez megtelt vagy meghibásodott</span>
|
<span class="toggle-label">{{T "settings_notifications.lemez_megtelt_vagy_meghibasodott"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_storage_disconnected" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "storage_disconnected"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_storage_disconnected" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "storage_disconnected"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Meghajtó leválasztva</span>
|
<span class="toggle-label">{{T "settings_notifications.meghajto_levalasztva"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_node_down" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "node_down"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_node_down" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "node_down"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Szerver nem elérhető</span>
|
<span class="toggle-label">{{T "settings_notifications.szerver_nem_elerheto"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_health_critical" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "health_critical"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_health_critical" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "health_critical"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Rendszer állapot kritikus</span>
|
<span class="toggle-label">{{T "settings_notifications.rendszer_allapot_kritikus"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_expected_backup_missed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "expected_backup_missed"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_expected_backup_missed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "expected_backup_missed"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Elvárt fájlmentés elmaradt</span>
|
<span class="toggle-label">{{T "settings_notifications.elvart_fajlmentes_elmaradt"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_expected_dbdump_missed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "expected_dbdump_missed"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_expected_dbdump_missed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "expected_dbdump_missed"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Elvárt adatbázismentés elmaradt</span>
|
<span class="toggle-label">{{T "settings_notifications.elvart_adatbazismentes_elmaradt"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_app_start_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "app_start_failed"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_app_start_failed" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "app_start_failed"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Alkalmazás nem fut</span>
|
<span class="toggle-label">{{T "settings_notifications.alkalmazas_nem_fut"}}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Tájékoztató:</label>
|
<label>{{T "settings_notifications.tajekoztato"}}</label>
|
||||||
<div class="checkbox-group">
|
<div class="checkbox-group">
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_storage_reconnected" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "storage_reconnected"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_storage_reconnected" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "storage_reconnected"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Meghajtó újra csatlakoztatva</span>
|
<span class="toggle-label">{{T "settings_notifications.meghajto_ujra_csatlakoztatva"}}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<input type="checkbox" name="event_health_recovered" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "health_recovered"}}checked{{end}}{{end}}{{end}}>
|
<input type="checkbox" name="event_health_recovered" {{with .NotificationPrefs}}{{range .EnabledEvents}}{{if eq . "health_recovered"}}checked{{end}}{{end}}{{end}}>
|
||||||
<span class="toggle-label">Rendszer állapot helyreállt</span>
|
<span class="toggle-label">{{T "settings_notifications.rendszer_allapot_helyreallt"}}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="cooldown_hours">Értesítési szünet</label>
|
<label for="cooldown_hours">{{T "settings_notifications.ertesitesi_szunet"}}</label>
|
||||||
<div class="form-inline">
|
<div class="form-inline">
|
||||||
<input type="number" id="cooldown_hours" name="cooldown_hours" min="1" max="168"
|
<input type="number" id="cooldown_hours" name="cooldown_hours" min="1" max="168"
|
||||||
value="{{with .NotificationPrefs}}{{.CooldownHours}}{{end}}"
|
value="{{with .NotificationPrefs}}{{.CooldownHours}}{{end}}"
|
||||||
class="form-control form-control-narrow">
|
class="form-control form-control-narrow">
|
||||||
<span class="form-hint">óra (azonos probléma esetén ennyi ideig nem küld újat)</span>
|
<span class="form-hint">{{T "settings_notifications.ora_azonos_problema_eseten_ennyi"}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-primary">Mentés</button>
|
<button type="submit" class="btn btn-primary">{{T "settings_notifications.mentes"}}</button>
|
||||||
<button type="submit" formaction="/settings/notifications/test" class="btn btn-outline">Teszt email küldése</button>
|
<button type="submit" formaction="/settings/notifications/test" class="btn btn-outline">{{T "settings_notifications.teszt_email_kuldese"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
Az értesítések a központi rendszeren keresztül működnek, ami jelenleg nincs bekapcsolva.
|
{{T "settings_notifications.az_ertesitesek_a_kozponti_rendszeren"}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
@@ -113,11 +113,9 @@
|
|||||||
<!-- Section: App email (SMTP relay) -->
|
<!-- Section: App email (SMTP relay) -->
|
||||||
{{if .AppEmailAvailable}}
|
{{if .AppEmailAvailable}}
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Alkalmazás-email</h3>
|
<h3>{{T "settings_notifications.alkalmazas_email"}}</h3>
|
||||||
<p class="settings-card-desc">
|
<p class="settings-card-desc">
|
||||||
Az alkalmazások a Felhom-on keresztül küldhetnek emailt (pl. jelszó-visszaállítás, meghívók),
|
{{T "settings_notifications.az_alkalmazasok_a_felhom_on"}}
|
||||||
külön email-szolgáltató beállítása nélkül. A feladó címe minden alkalmazásnál a saját
|
|
||||||
<em><alkalmazás>@felhom.eu</em> címe lesz.
|
|
||||||
</p>
|
</p>
|
||||||
{{if .AppEmailSuccess}}<div class="alert alert-info">{{.AppEmailSuccess}}</div>{{end}}
|
{{if .AppEmailSuccess}}<div class="alert alert-info">{{.AppEmailSuccess}}</div>{{end}}
|
||||||
{{if .AppEmailError}}<div class="alert alert-error">{{.AppEmailError}}</div>{{end}}
|
{{if .AppEmailError}}<div class="alert alert-error">{{.AppEmailError}}</div>{{end}}
|
||||||
@@ -126,21 +124,21 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label style="display:flex;align-items:center;gap:.5rem">
|
<label style="display:flex;align-items:center;gap:.5rem">
|
||||||
<input type="checkbox" name="app_email_enabled" value="on" {{if .AppEmailEnabled}}checked{{end}}>
|
<input type="checkbox" name="app_email_enabled" value="on" {{if .AppEmailEnabled}}checked{{end}}>
|
||||||
Alkalmazás-email engedélyezése
|
{{T "settings_notifications.alkalmazas_email_engedelyezese"}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="app_email_from_name">Feladó neve (opcionális)</label>
|
<label for="app_email_from_name">{{T "settings_notifications.felado_neve_opcionalis"}}</label>
|
||||||
<input type="text" id="app_email_from_name" name="app_email_from_name"
|
<input type="text" id="app_email_from_name" name="app_email_from_name"
|
||||||
value="{{.AppEmailFromName}}" placeholder="pl. a háztartás neve" class="form-control">
|
value="{{.AppEmailFromName}}" placeholder="{{T "settings_notifications.pl_a_haztartas_neve"}}" class="form-control">
|
||||||
<span class="form-hint">Ez jelenik meg a kimenő emailek feladójaként az alkalmazás neve mellett.</span>
|
<span class="form-hint">{{T "settings_notifications.ez_jelenik_meg_a_kimeno"}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-primary">Mentés</button>
|
<button type="submit" class="btn btn-primary">{{T "settings_notifications.mentes"}}</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<p class="settings-card-desc" style="margin-top:.75rem">
|
<p class="settings-card-desc" style="margin-top:.75rem">
|
||||||
Bekapcsolás után az egyes alkalmazásoknál is engedélyezni kell az email-küldést (az alkalmazás oldalán).
|
{{T "settings_notifications.bekapcsolas_utan_az_egyes_alkalmazasokna"}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -2,52 +2,51 @@
|
|||||||
{{template "layout_start" .}}
|
{{template "layout_start" .}}
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>Beállítások — Biztonság és hozzáférés</h2>
|
<h2>{{T "settings_security.beallitasok_biztonsag_es_hozzaferes"}}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Section B: Password Change -->
|
<!-- Section B: Password Change -->
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Jelszó módosítás</h3>
|
<h3>{{T "settings_security.jelszo_modositas"}}</h3>
|
||||||
{{if .AuthEnabled}}
|
{{if .AuthEnabled}}
|
||||||
{{if .PasswordError}}<div class="alert alert-error">{{.PasswordError}}</div>{{end}}
|
{{if .PasswordError}}<div class="alert alert-error">{{.PasswordError}}</div>{{end}}
|
||||||
<form method="POST" action="/settings/password">
|
<form method="POST" action="/settings/password">
|
||||||
{{.CSRFField}}
|
{{.CSRFField}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="current_password">Jelenlegi jelszó</label>
|
<label for="current_password">{{T "settings_security.jelenlegi_jelszo"}}</label>
|
||||||
<input type="password" id="current_password" name="current_password" required
|
<input type="password" id="current_password" name="current_password" required
|
||||||
placeholder="Adja meg a jelenlegi jelszavát" class="form-control">
|
placeholder="{{T "settings_security.adja_meg_a_jelenlegi_jelszavat"}}" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="new_password">Új jelszó</label>
|
<label for="new_password">{{T "settings_security.uj_jelszo"}}</label>
|
||||||
<input type="password" id="new_password" name="new_password" required minlength="8"
|
<input type="password" id="new_password" name="new_password" required minlength="8"
|
||||||
placeholder="Legalább 8 karakter" class="form-control">
|
placeholder="{{T "settings_security.legalabb_8_karakter"}}" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="confirm_password">Új jelszó megerősítése</label>
|
<label for="confirm_password">{{T "settings_security.uj_jelszo_megerositese"}}</label>
|
||||||
<input type="password" id="confirm_password" name="confirm_password" required minlength="8"
|
<input type="password" id="confirm_password" name="confirm_password" required minlength="8"
|
||||||
placeholder="Jelszó mégegyszer" class="form-control">
|
placeholder="{{T "settings_security.jelszo_megegyszer"}}" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary">Jelszó módosítása</button>
|
<button type="submit" class="btn btn-primary">{{T "settings_security.jelszo_modositasa"}}</button>
|
||||||
</form>
|
</form>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
A jelszavas védelem nincs beállítva. Kérd az üzemeltetőt a beállításhoz.
|
{{T "settings_security.a_jelszavas_vedelem_nincs_beallitva"}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Section: Geo-Restriction -->
|
<!-- Section: Geo-Restriction -->
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Földrajzi korlátozás</h3>
|
<h3>{{T "settings_security.foldrajzi_korlatozas"}}</h3>
|
||||||
<p class="settings-card-desc">
|
<p class="settings-card-desc">
|
||||||
Ország alapján korlátozható a webes alkalmazások elérése a Cloudflare WAF segítségével.
|
{{T "settings_security.orszag_alapjan_korlatozhato_a_webes"}}
|
||||||
<br><span class="form-hint">A helyi hálózati hozzáférés mindig engedélyezett (nem halad át a Cloudflare-en).</span>
|
<br><span class="form-hint">{{T "settings_security.a_helyi_halozati_hozzaferes_mindig"}}</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{{if not .CFConfigured}}
|
{{if not .CFConfigured}}
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
A Cloudflare API token nincs konfigurálva. Kérd az üzemeltetőt a beállításhoz.<br>
|
{{T "settings_security.a_cloudflare_api_token_nincs"}}
|
||||||
<small>A tokennek <strong>Zone WAF:Edit</strong> jogosultsággal kell rendelkeznie.</small>
|
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div id="geo-status-msg"></div>
|
<div id="geo-status-msg"></div>
|
||||||
@@ -55,16 +54,16 @@
|
|||||||
<label class="toggle" style="margin-bottom:1rem">
|
<label class="toggle" style="margin-bottom:1rem">
|
||||||
<input type="checkbox" id="geo-enabled" {{if .GeoEnabled}}checked{{end}}
|
<input type="checkbox" id="geo-enabled" {{if .GeoEnabled}}checked{{end}}
|
||||||
onchange="toggleGeo(this.checked)">
|
onchange="toggleGeo(this.checked)">
|
||||||
<span class="toggle-label">Geo-korlátozás aktív</span>
|
<span class="toggle-label">{{T "settings_security.geo_korlatozas_aktiv"}}</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div id="geo-details" {{if not .GeoEnabled}}style="display:none"{{end}}>
|
<div id="geo-details" {{if not .GeoEnabled}}style="display:none"{{end}}>
|
||||||
<!-- Global allowed countries -->
|
<!-- Global allowed countries -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Engedélyezett országok (globális)</label>
|
<label>{{T "settings_security.engedelyezett_orszagok_globalis"}}</label>
|
||||||
<div class="geo-country-selector" id="geo-countries">
|
<div class="geo-country-selector" id="geo-countries">
|
||||||
<input type="text" id="geo-search" class="form-control"
|
<input type="text" id="geo-search" class="form-control"
|
||||||
placeholder="Ország keresése..."
|
placeholder="{{T "settings_security.orszag_keresese"}}"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
oninput="filterCountries(this.value)"
|
oninput="filterCountries(this.value)"
|
||||||
onfocus="showCountryList()"
|
onfocus="showCountryList()"
|
||||||
@@ -72,22 +71,22 @@
|
|||||||
<div class="geo-country-list" id="geo-country-list"></div>
|
<div class="geo-country-list" id="geo-country-list"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="geo-selected-tags" id="geo-selected-tags"></div>
|
<div class="geo-selected-tags" id="geo-selected-tags"></div>
|
||||||
<span class="form-hint">Csak a kiválasztott országokból érhető el a rendszer.</span>
|
<span class="form-hint">{{T "settings_security.csak_a_kivalasztott_orszagokbol_erheto"}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Per-app overrides -->
|
<!-- Per-app overrides -->
|
||||||
<div class="form-group" style="margin-top:1.5rem">
|
<div class="form-group" style="margin-top:1.5rem">
|
||||||
<label>Alkalmazás-specifikus felülírások</label>
|
<label>{{T "settings_security.alkalmazas_specifikus_felulirasok"}}</label>
|
||||||
<div id="geo-app-overrides"></div>
|
<div id="geo-app-overrides"></div>
|
||||||
{{if .DeployedApps}}
|
{{if .DeployedApps}}
|
||||||
<div style="margin-top:.5rem;display:flex;align-items:center;gap:.5rem">
|
<div style="margin-top:.5rem;display:flex;align-items:center;gap:.5rem">
|
||||||
<select id="geo-add-app-select" class="form-control" style="max-width:250px">
|
<select id="geo-add-app-select" class="form-control" style="max-width:250px">
|
||||||
<option value="">— Alkalmazás kiválasztása —</option>
|
<option value="">{{T "settings_security.alkalmazas_kivalasztasa"}}</option>
|
||||||
{{range .DeployedApps}}
|
{{range .DeployedApps}}
|
||||||
<option value="{{.Name}}">{{.Display}}</option>
|
<option value="{{.Name}}">{{.Display}}</option>
|
||||||
{{end}}
|
{{end}}
|
||||||
</select>
|
</select>
|
||||||
<button class="btn btn-sm btn-outline" onclick="addAppOverride()">+ Hozzáadás</button>
|
<button class="btn btn-sm btn-outline" onclick="addAppOverride()">{{T "settings_security.hozzaadas"}}</button>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
@@ -96,11 +95,11 @@
|
|||||||
<div class="form-group" style="margin-top:1.5rem">
|
<div class="form-group" style="margin-top:1.5rem">
|
||||||
<div style="display:flex;align-items:center;gap:1rem;flex-wrap:wrap">
|
<div style="display:flex;align-items:center;gap:1rem;flex-wrap:wrap">
|
||||||
<button class="btn btn-primary" id="btn-geo-save" onclick="saveGeoSettings()">
|
<button class="btn btn-primary" id="btn-geo-save" onclick="saveGeoSettings()">
|
||||||
Mentés és szinkronizálás
|
{{T "settings_security.mentes_es_szinkronizalas"}}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm btn-outline" onclick="triggerGeoSync()">Kézi szinkronizálás</button>
|
<button class="btn btn-sm btn-outline" onclick="triggerGeoSync()">{{T "settings_security.kezi_szinkronizalas"}}</button>
|
||||||
<span id="geo-sync-status" class="form-hint">
|
<span id="geo-sync-status" class="form-hint">
|
||||||
{{if .GeoLastSync}}Utolsó szinkronizálás: {{.GeoLastSync}}{{end}}
|
{{if .GeoLastSync}}{{T "settings_security.utolso_szinkronizalas"}}{{end}}
|
||||||
{{if .GeoLastError}} <span class="state-text-crit">{{.GeoLastError}}</span>{{end}}
|
{{if .GeoLastError}} <span class="state-text-crit">{{.GeoLastError}}</span>{{end}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -118,10 +117,10 @@ function openDialog(opts){
|
|||||||
var root=document.getElementById('dialog-root');
|
var root=document.getElementById('dialog-root');
|
||||||
if(!root) return;
|
if(!root) return;
|
||||||
root.innerHTML='<div class="confirm-overlay" onclick="if(event.target===this)document.getElementById(\'dialog-cancel\').click()"><div class="confirm-box">'
|
root.innerHTML='<div class="confirm-overlay" onclick="if(event.target===this)document.getElementById(\'dialog-cancel\').click()"><div class="confirm-box">'
|
||||||
+'<h3>'+escText(opts.title||'Megerősítés')+'</h3>'
|
+'<h3>'+escText(opts.title||'{{T "settings_security.megerosites"}}')+'</h3>'
|
||||||
+'<p style="white-space:pre-line">'+escText(opts.message||'')+'</p>'
|
+'<p style="white-space:pre-line">'+escText(opts.message||'')+'</p>'
|
||||||
+'<div class="form-actions"><button id="dialog-go" class="btn btn-primary">'+escText(opts.confirmLabel||'Megerősítés')+'</button>'
|
+'<div class="form-actions"><button id="dialog-go" class="btn btn-primary">'+escText(opts.confirmLabel||'{{T "settings_security.megerosites"}}')+'</button>'
|
||||||
+'<button type="button" class="btn btn-outline" id="dialog-cancel">Mégsem</button></div>'
|
+'<button type="button" class="btn btn-outline" id="dialog-cancel">{{T "common.megsem"}}</button></div>'
|
||||||
+'</div></div>';
|
+'</div></div>';
|
||||||
document.getElementById('dialog-go').onclick=function(){ closeDialog(); if(opts.onConfirm) opts.onConfirm(); };
|
document.getElementById('dialog-go').onclick=function(){ closeDialog(); if(opts.onConfirm) opts.onConfirm(); };
|
||||||
document.getElementById('dialog-cancel').onclick=function(){ closeDialog(); if(opts.onCancel) opts.onCancel(); };
|
document.getElementById('dialog-cancel').onclick=function(){ closeDialog(); if(opts.onCancel) opts.onCancel(); };
|
||||||
@@ -171,7 +170,7 @@ function openDialog(opts){
|
|||||||
+ escHtml(c.name) + ' <small>(' + c.code + ')</small></div>';
|
+ escHtml(c.name) + ' <small>(' + c.code + ')</small></div>';
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
list.innerHTML = html || '<div class="geo-country-option" style="opacity:.5">Nincs találat</div>';
|
list.innerHTML = html || '<div class="geo-country-option" style="opacity:.5">{{T "settings_security.nincs_talalat"}}</div>';
|
||||||
// Reveal with 'block', NOT '' — the .geo-country-list CSS default is display:none,
|
// Reveal with 'block', NOT '' — the .geo-country-list CSS default is display:none,
|
||||||
// and clearing the inline style ('') would fall back to that and keep the (populated)
|
// and clearing the inline style ('') would fall back to that and keep the (populated)
|
||||||
// list hidden. This was the country-autocomplete "no list" bug.
|
// list hidden. This was the country-autocomplete "no list" bug.
|
||||||
@@ -188,8 +187,8 @@ function openDialog(opts){
|
|||||||
|
|
||||||
window.removeCountry = function(code) {
|
window.removeCountry = function(code) {
|
||||||
if (code === 'HU') {
|
if (code === 'HU') {
|
||||||
openDialog({title:'Figyelem', confirmLabel:'Eltávolítás',
|
openDialog({title:'{{T "settings_security.figyelem"}}', confirmLabel:'{{T "common.eltavolitas"}}',
|
||||||
message:'Figyelem: Magyarország eltávolítása azt jelenti, hogy magyar IP-ről sem lesz elérhető a rendszer távolról. Biztosan folytatja?',
|
message:'{{T "settings_security.figyelem_magyarorszag_eltavolitasa_azt_j"}}',
|
||||||
onConfirm:function(){ doRemoveCountry(code); }});
|
onConfirm:function(){ doRemoveCountry(code); }});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -247,8 +246,8 @@ function openDialog(opts){
|
|||||||
var idx = ov.allowed_countries.indexOf(code);
|
var idx = ov.allowed_countries.indexOf(code);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
if (code === 'HU') {
|
if (code === 'HU') {
|
||||||
openDialog({title:'Figyelem', confirmLabel:'Eltávolítás',
|
openDialog({title:'{{T "settings_security.figyelem"}}', confirmLabel:'{{T "common.eltavolitas"}}',
|
||||||
message:'Magyarország eltávolítása nem ajánlott. Folytatja?',
|
message:'{{T "settings_security.magyarorszag_eltavolitasa_nem_ajanlott_f"}}',
|
||||||
onConfirm:function(){ ov.allowed_countries.splice(ov.allowed_countries.indexOf(code), 1); },
|
onConfirm:function(){ ov.allowed_countries.splice(ov.allowed_countries.indexOf(code), 1); },
|
||||||
onCancel:function(){ el.checked = true; }});
|
onCancel:function(){ el.checked = true; }});
|
||||||
return;
|
return;
|
||||||
@@ -262,7 +261,7 @@ function openDialog(opts){
|
|||||||
function renderAppOverrides() {
|
function renderAppOverrides() {
|
||||||
var el = document.getElementById('geo-app-overrides');
|
var el = document.getElementById('geo-app-overrides');
|
||||||
if (!appOverrides || Object.keys(appOverrides).length === 0) {
|
if (!appOverrides || Object.keys(appOverrides).length === 0) {
|
||||||
el.innerHTML = '<p class="form-hint">Nincs alkalmazás-specifikus beállítás. Minden alkalmazás a globális beállítást követi.</p>';
|
el.innerHTML = '<p class="form-hint">{{T "settings_security.nincs_alkalmazas_specifikus_beallitas_mi"}}</p>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var html = '';
|
var html = '';
|
||||||
@@ -284,8 +283,8 @@ function openDialog(opts){
|
|||||||
html += '<span class="geo-tag geo-tag-sm">' + code + '</span>';
|
html += '<span class="geo-tag geo-tag-sm">' + code + '</span>';
|
||||||
}
|
}
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
html += '<button class="btn btn-sm btn-outline" onclick="editAppOverride(\'' + appName + '\')">Szerkesztés</button>';
|
html += '<button class="btn btn-sm btn-outline" onclick="editAppOverride(\'' + appName + '\')">{{T "settings_security.szerkesztes"}}</button>';
|
||||||
html += '<button class="btn btn-sm btn-danger-outline" onclick="removeAppOverride(\'' + appName + '\')">Törlés</button>';
|
html += '<button class="btn btn-sm btn-danger-outline" onclick="removeAppOverride(\'' + appName + '\')">{{T "common.torles"}}</button>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
}
|
}
|
||||||
el.innerHTML = html;
|
el.innerHTML = html;
|
||||||
@@ -298,7 +297,7 @@ function openDialog(opts){
|
|||||||
var checked = {};
|
var checked = {};
|
||||||
for (var i = 0; i < ov.allowed_countries.length; i++) checked[ov.allowed_countries[i]] = true;
|
for (var i = 0; i < ov.allowed_countries.length; i++) checked[ov.allowed_countries[i]] = true;
|
||||||
var html = '<div class="geo-edit-overlay" id="geo-edit-' + appName + '">';
|
var html = '<div class="geo-edit-overlay" id="geo-edit-' + appName + '">';
|
||||||
html += '<h4>Engedélyezett országok: ' + escHtml(appName) + '</h4>';
|
html += '<h4>{{T "settings_security.engedelyezett_orszagok"}} ' + escHtml(appName) + '</h4>';
|
||||||
html += '<div class="geo-edit-grid">';
|
html += '<div class="geo-edit-grid">';
|
||||||
for (var i = 0; i < allCountries.length; i++) {
|
for (var i = 0; i < allCountries.length; i++) {
|
||||||
var c = allCountries[i];
|
var c = allCountries[i];
|
||||||
@@ -307,7 +306,7 @@ function openDialog(opts){
|
|||||||
+ ' ' + escHtml(c.name) + ' (' + c.code + ')</label>';
|
+ ' ' + escHtml(c.name) + ' (' + c.code + ')</label>';
|
||||||
}
|
}
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
html += '<button class="btn btn-sm btn-primary" style="margin-top:.5rem" onclick="closeAppEdit(\'' + appName + '\')">Kész</button>';
|
html += '<button class="btn btn-sm btn-primary" style="margin-top:.5rem" onclick="closeAppEdit(\'' + appName + '\')">{{T "settings_security.kesz"}}</button>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
document.getElementById('geo-app-overrides').innerHTML += html;
|
document.getElementById('geo-app-overrides').innerHTML += html;
|
||||||
});
|
});
|
||||||
@@ -324,7 +323,7 @@ function openDialog(opts){
|
|||||||
var btn = document.getElementById('btn-geo-save');
|
var btn = document.getElementById('btn-geo-save');
|
||||||
var status = document.getElementById('geo-status-msg');
|
var status = document.getElementById('geo-status-msg');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.textContent = 'Mentés...';
|
btn.textContent = '{{T "settings_security.mentes"}}';
|
||||||
|
|
||||||
var payload = {
|
var payload = {
|
||||||
enabled: document.getElementById('geo-enabled').checked,
|
enabled: document.getElementById('geo-enabled').checked,
|
||||||
@@ -339,21 +338,21 @@ function openDialog(opts){
|
|||||||
.then(function(r){return r.json()})
|
.then(function(r){return r.json()})
|
||||||
.then(function(d){
|
.then(function(d){
|
||||||
if (d.ok) {
|
if (d.ok) {
|
||||||
status.innerHTML = '<div class="alert alert-info">' + (d.message || 'Mentve') + '</div>';
|
status.innerHTML = '<div class="alert alert-info">' + (d.message || '{{T "settings_security.mentve"}}') + '</div>';
|
||||||
// Save per-app overrides
|
// Save per-app overrides
|
||||||
if (appOverrides && Object.keys(appOverrides).length > 0) {
|
if (appOverrides && Object.keys(appOverrides).length > 0) {
|
||||||
saveAllAppOverrides();
|
saveAllAppOverrides();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
status.innerHTML = '<div class="alert alert-error">' + (d.error || 'Hiba') + '</div>';
|
status.innerHTML = '<div class="alert alert-error">' + (d.error || '{{T "common.hiba"}}') + '</div>';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function(err){
|
.catch(function(err){
|
||||||
status.innerHTML = '<div class="alert alert-error">Hálózati hiba</div>';
|
status.innerHTML = '<div class="alert alert-error">{{T "settings_security.halozati_hiba"}}</div>';
|
||||||
})
|
})
|
||||||
.finally(function(){
|
.finally(function(){
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = 'Mentés és szinkronizálás';
|
btn.textContent = '{{T "settings_security.mentes_es_szinkronizalas"}}';
|
||||||
setTimeout(function(){ status.innerHTML = ''; }, 8000);
|
setTimeout(function(){ status.innerHTML = ''; }, 8000);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -375,7 +374,7 @@ function openDialog(opts){
|
|||||||
.then(function(r){return r.json()})
|
.then(function(r){return r.json()})
|
||||||
.then(function(d){
|
.then(function(d){
|
||||||
var status = document.getElementById('geo-sync-status');
|
var status = document.getElementById('geo-sync-status');
|
||||||
status.textContent = d.ok ? 'Szinkronizálás elindítva...' : (d.error || 'Hiba');
|
status.textContent = d.ok ? '{{T "settings_security.szinkronizalas_elinditva"}}' : (d.error || '{{T "common.hiba"}}');
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
fetch('/api/geo/status', {headers: csrfHeaders()})
|
fetch('/api/geo/status', {headers: csrfHeaders()})
|
||||||
.then(function(r){return r.json()})
|
.then(function(r){return r.json()})
|
||||||
@@ -383,7 +382,7 @@ function openDialog(opts){
|
|||||||
if (d.ok && d.data) {
|
if (d.ok && d.data) {
|
||||||
var sync = d.data.last_sync || '';
|
var sync = d.data.last_sync || '';
|
||||||
var err = d.data.last_sync_error || '';
|
var err = d.data.last_sync_error || '';
|
||||||
status.innerHTML = sync ? ('Utolsó: ' + sync.substring(0,19).replace('T',' ')) : '';
|
status.innerHTML = sync ? ('{{T "settings_security.utolso"}} ' + sync.substring(0,19).replace('T',' ')) : '';
|
||||||
if (err) status.innerHTML += ' <span class="state-text-crit">' + escHtml(err) + '</span>';
|
if (err) status.innerHTML += ' <span class="state-text-crit">' + escHtml(err) + '</span>';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -407,13 +406,13 @@ function openDialog(opts){
|
|||||||
<!-- Section: Recovery Info -->
|
<!-- Section: Recovery Info -->
|
||||||
{{if .HasRetrievalPassword}}
|
{{if .HasRetrievalPassword}}
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Vészhelyzeti információk</h3>
|
<h3>{{T "settings_security.veszhelyzeti_informaciok"}}</h3>
|
||||||
<p class="settings-card-desc">
|
<p class="settings-card-desc">
|
||||||
Ezeket az adatokat mentse el biztos helyre. Újratelepítés esetén szükség lesz rájuk a rendszer visszaállításához.
|
{{T "settings_security.ezeket_az_adatokat_mentse_el"}}
|
||||||
</p>
|
</p>
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Ügyfél azonosító</span>
|
<span class="settings-label">{{T "common.ugyfel_azonosito"}}</span>
|
||||||
<span class="settings-value mono">{{.CustomerID}}</span>
|
<span class="settings-value mono">{{.CustomerID}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
@@ -421,22 +420,20 @@ function openDialog(opts){
|
|||||||
<span class="settings-value mono">{{.HubURL}}</span>
|
<span class="settings-value mono">{{.HubURL}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Visszaállítási jelszó</span>
|
<span class="settings-label">{{T "settings_security.visszaallitasi_jelszo"}}</span>
|
||||||
<!-- R-249: the value is NOT in this page. The old markup rendered it into a
|
<!-- R-249: the value is NOT in this page. The old markup rendered it into a
|
||||||
display:none span, which hid it from the eye and from nothing else — a fetch of the
|
display:none span, which hid it from the eye and from nothing else — a fetch of the
|
||||||
page returned the plaintext. „Megjelenít" now asks the server for it. -->
|
page returned the plaintext. „Megjelenít" now asks the server for it. -->
|
||||||
<span class="settings-value">
|
<span class="settings-value">
|
||||||
<span id="retrieval-pw-slot" class="mono">••••••••••••••••</span>
|
<span id="retrieval-pw-slot" class="mono">••••••••••••••••</span>
|
||||||
<button type="button" id="retrieval-pw-btn" class="btn btn-xs btn-outline" onclick="revealRetrievalPw()">Megjelenít</button>
|
<button type="button" id="retrieval-pw-btn" class="btn btn-xs btn-outline" onclick="revealRetrievalPw()">{{T "settings_security.megjelenit"}}</button>
|
||||||
<span id="retrieval-pw-err" class="form-hint" style="display:none;color:var(--red)"></span>
|
<span id="retrieval-pw-err" class="form-hint" style="display:none;color:var(--red)"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Támogatás</span>
|
<span class="settings-label">{{T "settings_security.tamogatas"}}</span>
|
||||||
<span class="settings-value">
|
<span class="settings-value">
|
||||||
<a href="mailto:{{.SupportEmail}}" style="color: var(--blue);">{{.SupportEmail}}</a>
|
{{T "settings_security.felhom_eu_kapcsolat"}}
|
||||||
|
|
|
||||||
<a href="{{.SupportURL}}" target="_blank" style="color: var(--blue);">felhom.eu/kapcsolat</a>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -451,7 +448,7 @@ function revealRetrievalPw() {
|
|||||||
err.style.display = 'none';
|
err.style.display = 'none';
|
||||||
if (btn.dataset.shown === '1') { // „Elrejt" — drop the value out of the DOM again
|
if (btn.dataset.shown === '1') { // „Elrejt" — drop the value out of the DOM again
|
||||||
slot.textContent = '••••••••••••••••';
|
slot.textContent = '••••••••••••••••';
|
||||||
btn.textContent = 'Megjelenít';
|
btn.textContent = '{{T "settings_security.megjelenit"}}';
|
||||||
btn.dataset.shown = '';
|
btn.dataset.shown = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -463,16 +460,16 @@ function revealRetrievalPw() {
|
|||||||
}).then(function (r) { return r.json(); }).then(function (j) {
|
}).then(function (r) { return r.json(); }).then(function (j) {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
if (!j.ok) {
|
if (!j.ok) {
|
||||||
err.textContent = j.error || 'A visszaállítási jelszó lekérése nem sikerült.';
|
err.textContent = j.error || '{{T "settings_security.a_visszaallitasi_jelszo_lekerese_nem"}}';
|
||||||
err.style.display = 'inline';
|
err.style.display = 'inline';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
slot.textContent = j.data.password;
|
slot.textContent = j.data.password;
|
||||||
btn.textContent = 'Elrejt';
|
btn.textContent = '{{T "settings_security.elrejt"}}';
|
||||||
btn.dataset.shown = '1';
|
btn.dataset.shown = '1';
|
||||||
}).catch(function () {
|
}).catch(function () {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
err.textContent = 'A visszaállítási jelszó lekérése nem sikerült.';
|
err.textContent = '{{T "settings_security.a_visszaallitasi_jelszo_lekerese_nem"}}';
|
||||||
err.style.display = 'inline';
|
err.style.display = 'inline';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,20 +2,20 @@
|
|||||||
{{template "layout_start" .}}
|
{{template "layout_start" .}}
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>Beállítások — Rendszer</h2>
|
<h2>{{T "settings_system.beallitasok_rendszer"}}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Section A: System Configuration (read-only) -->
|
<!-- Section A: System Configuration (read-only) -->
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Rendszer konfiguráció</h3>
|
<h3>{{T "settings_system.rendszer_konfiguracio"}}</h3>
|
||||||
<p class="settings-card-desc">Az üzemeltető által beállított értékek. Módosításhoz kérd az üzemeltetőt.</p>
|
<p class="settings-card-desc">{{T "settings_system.az_uzemelteto_altal_beallitott_ertekek"}}</p>
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Ügyfél azonosító</span>
|
<span class="settings-label">{{T "common.ugyfel_azonosito"}}</span>
|
||||||
<span class="settings-value mono">{{.CustomerID}}</span>
|
<span class="settings-value mono">{{.CustomerID}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Ügyfél neve</span>
|
<span class="settings-label">{{T "settings_system.ugyfel_neve"}}</span>
|
||||||
<span class="settings-value">{{.CustomerName}}</span>
|
<span class="settings-value">{{.CustomerName}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
@@ -24,27 +24,27 @@
|
|||||||
</div>
|
</div>
|
||||||
{{if .GitRepoURL}}
|
{{if .GitRepoURL}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Alkalmazás sablon forrás</span>
|
<span class="settings-label">{{T "settings_system.alkalmazas_sablon_forras"}}</span>
|
||||||
<span class="settings-value mono settings-value-truncate">{{.GitRepoURL}}</span>
|
<span class="settings-value mono settings-value-truncate">{{.GitRepoURL}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Sablon szinkronizálás</span>
|
<span class="settings-label">{{T "settings_system.sablon_szinkronizalas"}}</span>
|
||||||
<span class="settings-value mono">{{.GitSyncInterval}}</span>
|
<span class="settings-value mono">{{.GitSyncInterval}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Biztonsági mentés</span>
|
<span class="settings-label">{{T "settings_system.biztonsagi_mentes"}}</span>
|
||||||
<span class="settings-value">{{if .BackupEnabled}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> Aktív</span>{{else}}<span class="state-text-neutral">Inaktív</span>{{end}}</span>
|
<span class="settings-value">{{if .BackupEnabled}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> {{T "settings_system.aktiv"}}</span>{{else}}<span class="state-text-neutral">{{T "settings_system.inaktiv"}}</span>{{end}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{if .BackupEnabled}}
|
{{if .BackupEnabled}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Mentés ütemezés</span>
|
<span class="settings-label">{{T "settings_system.mentes_utemezes"}}</span>
|
||||||
<span class="settings-value mono">{{.DBDumpSchedule}} / {{.ResticSchedule}}</span>
|
<span class="settings-value mono">{{.DBDumpSchedule}} / {{.ResticSchedule}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Monitoring</span>
|
<span class="settings-label">Monitoring</span>
|
||||||
<span class="settings-value">{{if .MonitoringEnabled}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> Aktív</span>{{else}}<span class="state-text-neutral">Inaktív</span>{{end}}</span>
|
<span class="settings-value">{{if .MonitoringEnabled}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> {{T "settings_system.aktiv"}}</span>{{else}}<span class="state-text-neutral">{{T "settings_system.inaktiv"}}</span>{{end}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{if .MonitoringEnabled}}
|
{{if .MonitoringEnabled}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
@@ -53,78 +53,78 @@
|
|||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Hub jelentés</span>
|
<span class="settings-label">{{T "settings_system.hub_jelentes"}}</span>
|
||||||
<span class="settings-value">{{if .HubEnabled}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> Aktív</span>{{else}}–{{end}}</span>
|
<span class="settings-value">{{if .HubEnabled}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> {{T "settings_system.aktiv"}}</span>{{else}}–{{end}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Section: Version & Update -->
|
<!-- Section: Version & Update -->
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Verzió és frissítés</h3>
|
<h3>{{T "settings_system.verzio_es_frissites"}}</h3>
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Jelenlegi verzió</span>
|
<span class="settings-label">{{T "settings_system.jelenlegi_verzio"}}</span>
|
||||||
<span class="settings-value mono">{{.Version}}</span>
|
<span class="settings-value mono">{{.Version}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{if .SelfUpdateEnabled}}
|
{{if .SelfUpdateEnabled}}
|
||||||
{{if .LatestVersion}}
|
{{if .LatestVersion}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Legújabb verzió</span>
|
<span class="settings-label">{{T "settings_system.legujabb_verzio"}}</span>
|
||||||
<span class="settings-value mono">
|
<span class="settings-value mono">
|
||||||
{{.LatestVersion}}
|
{{.LatestVersion}}
|
||||||
{{if .UpdateAvailable}}
|
{{if .UpdateAvailable}}
|
||||||
<span class="state-text-run" style="margin-left:0.5em;">● Frissítés elérhető</span>
|
<span class="state-text-run" style="margin-left:0.5em;">{{T "settings_system.frissites_elerheto"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
<span style="margin-left:0.5em; color:var(--text-3);">— naprakész</span>
|
<span style="margin-left:0.5em; color:var(--text-3);">{{T "settings_system.naprakesz"}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .LastCheckTime}}
|
{{if .LastCheckTime}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Utolsó ellenőrzés</span>
|
<span class="settings-label">{{T "settings_system.utolso_ellenorzes"}}</span>
|
||||||
<span class="settings-value mono">{{.LastCheckTime}}</span>
|
<span class="settings-value mono">{{.LastCheckTime}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Registry</span>
|
<span class="settings-label">Registry</span>
|
||||||
<span class="settings-value">{{if .RegistryAnonymous}}nyilvános (hitelesítés nélkül){{else}}hitelesített{{end}}</span>
|
<span class="settings-value">{{if .RegistryAnonymous}}{{T "settings_system.nyilvanos_hitelesites_nelkul"}}{{else}}{{T "settings_system.hitelesitett"}}{{end}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{if .LastCheckError}}
|
{{if .LastCheckError}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Hiba</span>
|
<span class="settings-label">{{T "common.hiba"}}</span>
|
||||||
<span class="settings-value state-text-crit">{{.LastCheckError}}</span>
|
<span class="settings-value state-text-crit">{{.LastCheckError}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Automatikus frissítés</span>
|
<span class="settings-label">{{T "settings_system.automatikus_frissites"}}</span>
|
||||||
<span class="settings-value">
|
<span class="settings-value">
|
||||||
{{if .AutoUpdateEnabled}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> Aktív</span> <span class="mono">({{.AutoUpdateTime}})</span>{{else}}–{{end}}
|
{{if .AutoUpdateEnabled}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> {{T "settings_system.aktiv"}}</span> <span class="mono">({{.AutoUpdateTime}})</span>{{else}}–{{end}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{if .ControllerFloor}}
|
{{if .ControllerFloor}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Minimális verzió (üzemeltető)</span>
|
<span class="settings-label">{{T "settings_system.minimalis_verzio_uzemelteto"}}</span>
|
||||||
<span class="settings-value mono">
|
<span class="settings-value mono">
|
||||||
{{.ControllerFloor}}
|
{{.ControllerFloor}}
|
||||||
<span style="margin-left:0.5em; color:#888;">— a rendszer automatikusan erre a verzióra frissít, ha régebbi</span>
|
<span style="margin-left:0.5em; color:#888;">{{T "settings_system.a_rendszer_automatikusan_erre_a"}}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .UpdateRunning}}
|
{{if .UpdateRunning}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Állapot</span>
|
<span class="settings-label">{{T "settings_system.allapot"}}</span>
|
||||||
<span class="settings-value state-text-progress" id="auto-update-status"><svg class="ico ico-sm ico-spin"><use href="#i-rotate-cw"/></svg> Frissítés folyamatban — a vezérlő hamarosan újraindul…</span>
|
<span class="settings-value state-text-progress" id="auto-update-status"><svg class="ico ico-sm ico-spin"><use href="#i-rotate-cw"/></svg> {{T "settings_system.frissites_folyamatban_a_vezerlo_hamarosa"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{with .LastUpdateState}}
|
{{with .LastUpdateState}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Utolsó frissítés</span>
|
<span class="settings-label">{{T "settings_system.utolso_frissites"}}</span>
|
||||||
<span class="settings-value">
|
<span class="settings-value">
|
||||||
{{if eq .Status "success"}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> Sikeres</span> ({{.PreviousVersion}} → {{.TargetVersion}})
|
{{if eq .Status "success"}}<span class="state-text-run"><svg class="ico ico-sm"><use href="#i-check"/></svg> {{T "settings_system.sikeres"}}</span> ({{.PreviousVersion}} → {{.TargetVersion}})
|
||||||
{{else if eq .Status "failed"}}<span class="state-text-crit"><svg class="ico ico-sm"><use href="#i-x"/></svg> Sikertelen</span> — {{.Error}}
|
{{else if eq .Status "failed"}}<span class="state-text-crit"><svg class="ico ico-sm"><use href="#i-x"/></svg> {{T "settings_system.sikertelen"}}</span> — {{.Error}}
|
||||||
{{else if eq .Status "pending"}}<span class="state-text-progress"><svg class="ico ico-sm ico-spin"><use href="#i-rotate-cw"/></svg> Folyamatban</span>
|
{{else if eq .Status "pending"}}<span class="state-text-progress"><svg class="ico ico-sm ico-spin"><use href="#i-rotate-cw"/></svg> {{T "settings_system.folyamatban"}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -132,9 +132,9 @@
|
|||||||
<div class="settings-row" style="padding-top: 0.5em;">
|
<div class="settings-row" style="padding-top: 0.5em;">
|
||||||
<span class="settings-label"></span>
|
<span class="settings-label"></span>
|
||||||
<span class="settings-value">
|
<span class="settings-value">
|
||||||
<button class="btn btn-secondary btn-sm" id="btn-check-update" onclick="checkUpdate()">Frissítés keresése</button>
|
<button class="btn btn-secondary btn-sm" id="btn-check-update" onclick="checkUpdate()">{{T "settings_system.frissites_keresese"}}</button>
|
||||||
{{if .UpdateAvailable}}
|
{{if .UpdateAvailable}}
|
||||||
<button class="btn btn-primary btn-sm" id="btn-trigger-update" onclick="triggerUpdate()" style="margin-left:0.5em;">Frissítés telepítése</button>
|
<button class="btn btn-primary btn-sm" id="btn-trigger-update" onclick="triggerUpdate()" style="margin-left:0.5em;">{{T "settings_system.frissites_telepitese"}}</button>
|
||||||
{{end}}
|
{{end}}
|
||||||
<span id="update-status-msg" style="margin-left:0.5em; display:none;"></span>
|
<span id="update-status-msg" style="margin-left:0.5em; display:none;"></span>
|
||||||
</span>
|
</span>
|
||||||
@@ -147,50 +147,50 @@
|
|||||||
stored NOWHERE (S-5: a DHCP lease persisted anywhere eventually misdirects people); a missing
|
stored NOWHERE (S-5: a DHCP lease persisted anywhere eventually misdirects people); a missing
|
||||||
value renders „—" because an address-less row beats a wrong address. -->
|
value renders „—" because an address-less row beats a wrong address. -->
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Hálózat</h3>
|
<h3>{{T "settings_system.halozat"}}</h3>
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Helyi cím (LAN)</span>
|
<span class="settings-label">{{T "settings_system.helyi_cim_lan"}}</span>
|
||||||
<span class="settings-value mono">{{if .NetLANAddress}}{{.NetLANAddress}}{{else}}— <span style="color:var(--text-3);">nem állapítható meg</span>{{end}}</span>
|
<span class="settings-value mono">{{if .NetLANAddress}}{{.NetLANAddress}}{{else}}— <span style="color:var(--text-3);">{{T "settings_system.nem_allapithato_meg"}}</span>{{end}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{if .NetSMBName}}
|
{{if .NetSMBName}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Hálózati név</span>
|
<span class="settings-label">{{T "settings_system.halozati_nev"}}</span>
|
||||||
<span class="settings-value mono">\\{{.NetSMBName}}</span>
|
<span class="settings-value mono">\\{{.NetSMBName}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Átjáró</span>
|
<span class="settings-label">{{T "settings_system.atjaro"}}</span>
|
||||||
<span class="settings-value mono">{{if .NetGateway}}{{.NetGateway}}{{else}}— <span style="color:var(--text-3);">nem állapítható meg</span>{{end}}</span>
|
<span class="settings-value mono">{{if .NetGateway}}{{.NetGateway}}{{else}}— <span style="color:var(--text-3);">{{T "settings_system.nem_allapithato_meg"}}</span>{{end}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="settings-card-desc" style="margin-top:0.5em;">Ezek az értékek a helyi hálózattól függenek és változhatnak. Távoli hibaelhárításnál ezt az oldalt kérjük felolvasni.</p>
|
<p class="settings-card-desc" style="margin-top:0.5em;">{{T "settings_system.ezek_az_ertekek_a_helyi"}}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Szerver memória (RAM)</h3>
|
<h3>{{T "settings_system.szerver_memoria_ram"}}</h3>
|
||||||
{{if .MemorySupported}}
|
{{if .MemorySupported}}
|
||||||
{{if .MemoryReachable}}
|
{{if .MemoryReachable}}
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Jelenlegi memória</span>
|
<span class="settings-label">{{T "settings_system.jelenlegi_memoria"}}</span>
|
||||||
<span class="settings-value mono">{{.MemoryAllocatedMB}} MB</span>
|
<span class="settings-value mono">{{.MemoryAllocatedMB}} MB</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Felhasznált</span>
|
<span class="settings-label">{{T "settings_system.felhasznalt"}}</span>
|
||||||
<span class="settings-value mono">{{.MemoryUsageMB}} MB</span>
|
<span class="settings-value mono">{{.MemoryUsageMB}} MB</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Megengedett tartomány</span>
|
<span class="settings-label">{{T "settings_system.megengedett_tartomany"}}</span>
|
||||||
<span class="settings-value mono">{{.MemoryMinMB}} MB – {{.MemoryMaxMB}} MB</span>
|
<span class="settings-value mono">{{.MemoryMinMB}} MB – {{.MemoryMaxMB}} MB</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-row" style="padding-top: 0.5em;">
|
<div class="settings-row" style="padding-top: 0.5em;">
|
||||||
<span class="settings-label">Új méret (MB)</span>
|
<span class="settings-label">{{T "settings_system.uj_meret_mb"}}</span>
|
||||||
<span class="settings-value">
|
<span class="settings-value">
|
||||||
<input type="number" id="mem-input" class="input mono" style="width:8em;"
|
<input type="number" id="mem-input" class="input mono" style="width:8em;"
|
||||||
value="{{.MemoryAllocatedMB}}" min="{{.MemoryMinMB}}" max="{{.MemoryMaxMB}}" step="256"
|
value="{{.MemoryAllocatedMB}}" min="{{.MemoryMinMB}}" max="{{.MemoryMaxMB}}" step="256"
|
||||||
data-current="{{.MemoryAllocatedMB}}">
|
data-current="{{.MemoryAllocatedMB}}">
|
||||||
<button class="btn btn-primary btn-sm" id="btn-mem-resize" onclick="resizeMemory()" style="margin-left:0.5em;">Átméretezés</button>
|
<button class="btn btn-primary btn-sm" id="btn-mem-resize" onclick="resizeMemory()" style="margin-left:0.5em;">{{T "settings_system.atmeretezes"}}</button>
|
||||||
<span id="mem-status-msg" style="margin-left:0.5em; display:none;"></span>
|
<span id="mem-status-msg" style="margin-left:0.5em; display:none;"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -198,14 +198,14 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
<div class="settings-grid">
|
<div class="settings-grid">
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="settings-label">Jelenlegi memória</span>
|
<span class="settings-label">{{T "settings_system.jelenlegi_memoria"}}</span>
|
||||||
<span class="settings-value mono">{{if .MemoryProcMB}}{{.MemoryProcMB}} MB{{else}}n/a{{end}}</span>
|
<span class="settings-value mono">{{if .MemoryProcMB}}{{.MemoryProcMB}} MB{{else}}n/a{{end}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="settings-card-desc">A kiszolgáló ügynök jelenleg nem elérhető — próbáld meg később.</p>
|
<p class="settings-card-desc">{{T "settings_system.a_kiszolgalo_ugynok_jelenleg_nem"}}</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<p class="settings-card-desc">A memória átméretezéséhez a kiszolgáló rendszerfrissítése szükséges.</p>
|
<p class="settings-card-desc">{{T "settings_system.a_memoria_atmeretezesehez_a_kiszolgalo"}}</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -218,10 +218,10 @@ function openDialog(opts){
|
|||||||
var root=document.getElementById('dialog-root');
|
var root=document.getElementById('dialog-root');
|
||||||
if(!root) return;
|
if(!root) return;
|
||||||
root.innerHTML='<div class="confirm-overlay" onclick="if(event.target===this)document.getElementById(\'dialog-cancel\').click()"><div class="confirm-box">'
|
root.innerHTML='<div class="confirm-overlay" onclick="if(event.target===this)document.getElementById(\'dialog-cancel\').click()"><div class="confirm-box">'
|
||||||
+'<h3>'+escText(opts.title||'Megerősítés')+'</h3>'
|
+'<h3>'+escText(opts.title||'{{T "settings_system.megerosites"}}')+'</h3>'
|
||||||
+'<p style="white-space:pre-line">'+escText(opts.message||'')+'</p>'
|
+'<p style="white-space:pre-line">'+escText(opts.message||'')+'</p>'
|
||||||
+'<div class="form-actions"><button id="dialog-go" class="btn btn-primary">'+escText(opts.confirmLabel||'Megerősítés')+'</button>'
|
+'<div class="form-actions"><button id="dialog-go" class="btn btn-primary">'+escText(opts.confirmLabel||'{{T "settings_system.megerosites"}}')+'</button>'
|
||||||
+'<button type="button" class="btn btn-outline" id="dialog-cancel">Mégsem</button></div>'
|
+'<button type="button" class="btn btn-outline" id="dialog-cancel">{{T "common.megsem"}}</button></div>'
|
||||||
+'</div></div>';
|
+'</div></div>';
|
||||||
document.getElementById('dialog-go').onclick=function(){ closeDialog(); if(opts.onConfirm) opts.onConfirm(); };
|
document.getElementById('dialog-go').onclick=function(){ closeDialog(); if(opts.onConfirm) opts.onConfirm(); };
|
||||||
document.getElementById('dialog-cancel').onclick=function(){ closeDialog(); if(opts.onCancel) opts.onCancel(); };
|
document.getElementById('dialog-cancel').onclick=function(){ closeDialog(); if(opts.onCancel) opts.onCancel(); };
|
||||||
@@ -231,7 +231,7 @@ function checkUpdate() {
|
|||||||
var btn = document.getElementById('btn-check-update');
|
var btn = document.getElementById('btn-check-update');
|
||||||
var msg = document.getElementById('update-status-msg');
|
var msg = document.getElementById('update-status-msg');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.textContent = 'Ellenőrzés...';
|
btn.textContent = '{{T "settings_system.ellenorzes"}}';
|
||||||
msg.style.display = 'none';
|
msg.style.display = 'none';
|
||||||
fetch('/api/selfupdate/check', {method:'POST', headers: csrfHeaders()})
|
fetch('/api/selfupdate/check', {method:'POST', headers: csrfHeaders()})
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) { return r.json(); })
|
||||||
@@ -239,23 +239,23 @@ function checkUpdate() {
|
|||||||
if (data.ok) {
|
if (data.ok) {
|
||||||
location.reload();
|
location.reload();
|
||||||
} else {
|
} else {
|
||||||
msg.textContent = data.error || 'Hiba történt';
|
msg.textContent = data.error || '{{T "common.hiba_tortent"}}';
|
||||||
msg.style.display = 'inline';
|
msg.style.display = 'inline';
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = 'Frissítés keresése';
|
btn.textContent = '{{T "settings_system.frissites_keresese"}}';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function() {
|
.catch(function() {
|
||||||
msg.textContent = 'Kapcsolódási hiba';
|
msg.textContent = '{{T "settings_system.kapcsolodasi_hiba"}}';
|
||||||
msg.style.display = 'inline';
|
msg.style.display = 'inline';
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = 'Frissítés keresése';
|
btn.textContent = '{{T "settings_system.frissites_keresese"}}';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function triggerUpdate() {
|
function triggerUpdate() {
|
||||||
openDialog({title:'Vezérlő frissítése', confirmLabel:'Frissítés',
|
openDialog({title:'{{T "settings_system.vezerlo_frissitese"}}', confirmLabel:'{{T "settings_system.frissites"}}',
|
||||||
message:'Biztosan frissíti a controllert?\n\nA folyamat alatt a vezérlőpult rövid időre elérhetetlenné válik.',
|
message:'{{T "settings_system.biztosan_frissiti_a_controllert_n"}}',
|
||||||
onConfirm:doTriggerUpdate});
|
onConfirm:doTriggerUpdate});
|
||||||
}
|
}
|
||||||
function doTriggerUpdate() {
|
function doTriggerUpdate() {
|
||||||
@@ -263,25 +263,25 @@ function doTriggerUpdate() {
|
|||||||
var checkBtn = document.getElementById('btn-check-update');
|
var checkBtn = document.getElementById('btn-check-update');
|
||||||
var msg = document.getElementById('update-status-msg');
|
var msg = document.getElementById('update-status-msg');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.textContent = 'Frissítés...';
|
btn.textContent = '{{T "settings_system.frissites_2"}}';
|
||||||
if (checkBtn) checkBtn.disabled = true;
|
if (checkBtn) checkBtn.disabled = true;
|
||||||
msg.textContent = 'Frissítés folyamatban...';
|
msg.textContent = '{{T "settings_system.frissites_folyamatban"}}';
|
||||||
msg.style.display = 'inline';
|
msg.style.display = 'inline';
|
||||||
fetch('/api/selfupdate/update', {method:'POST', headers: csrfHeaders()})
|
fetch('/api/selfupdate/update', {method:'POST', headers: csrfHeaders()})
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) { return r.json(); })
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (data.ok) {
|
if (data.ok) {
|
||||||
msg.textContent = 'Újraindulás...';
|
msg.textContent = '{{T "settings_system.ujraindulas"}}';
|
||||||
pollUntilBack();
|
pollUntilBack();
|
||||||
} else {
|
} else {
|
||||||
msg.textContent = data.error || 'Hiba történt';
|
msg.textContent = data.error || '{{T "common.hiba_tortent"}}';
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = 'Frissítés telepítése';
|
btn.textContent = '{{T "settings_system.frissites_telepitese"}}';
|
||||||
if (checkBtn) checkBtn.disabled = false;
|
if (checkBtn) checkBtn.disabled = false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function() {
|
.catch(function() {
|
||||||
msg.textContent = 'Kapcsolódási hiba';
|
msg.textContent = '{{T "settings_system.kapcsolodasi_hiba"}}';
|
||||||
pollUntilBack();
|
pollUntilBack();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -291,12 +291,12 @@ function resizeMemory() {
|
|||||||
var target = parseInt(input.value, 10);
|
var target = parseInt(input.value, 10);
|
||||||
var current = parseInt(input.getAttribute('data-current'), 10);
|
var current = parseInt(input.getAttribute('data-current'), 10);
|
||||||
if (isNaN(target) || target <= 0) {
|
if (isNaN(target) || target <= 0) {
|
||||||
showMemMsg('Érvénytelen memória érték', true);
|
showMemMsg('{{T "settings_system.ervenytelen_memoria_ertek"}}', true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (target < current) {
|
if (target < current) {
|
||||||
openDialog({title:'Memória csökkentése', confirmLabel:'Csökkentés',
|
openDialog({title:'{{T "settings_system.memoria_csokkentese"}}', confirmLabel:'{{T "settings_system.csokkentes"}}',
|
||||||
message:'A memória csökkentése hatással lehet a futó alkalmazások teljesítményére. Biztosan folytatod?',
|
message:'{{T "settings_system.a_memoria_csokkentese_hatassal_lehet"}}',
|
||||||
onConfirm:function(){ doResizeMemory(target); }});
|
onConfirm:function(){ doResizeMemory(target); }});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -305,7 +305,7 @@ function resizeMemory() {
|
|||||||
function doResizeMemory(target) {
|
function doResizeMemory(target) {
|
||||||
var btn = document.getElementById('btn-mem-resize');
|
var btn = document.getElementById('btn-mem-resize');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.textContent = 'Átméretezés...';
|
btn.textContent = '{{T "settings_system.atmeretezes_2"}}';
|
||||||
fetch('/api/system/memory/resize', {
|
fetch('/api/system/memory/resize', {
|
||||||
method:'POST', headers: Object.assign({'Content-Type':'application/json'}, csrfHeaders()),
|
method:'POST', headers: Object.assign({'Content-Type':'application/json'}, csrfHeaders()),
|
||||||
body: JSON.stringify({memory_mb: target})
|
body: JSON.stringify({memory_mb: target})
|
||||||
@@ -313,18 +313,18 @@ function doResizeMemory(target) {
|
|||||||
.then(function(r) { return r.json(); })
|
.then(function(r) { return r.json(); })
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
if (data.ok) {
|
if (data.ok) {
|
||||||
showMemMsg(data.error || data.message || 'Kész.', false);
|
showMemMsg(data.error || data.message || '{{T "settings_system.kesz"}}', false);
|
||||||
setTimeout(function(){ location.reload(); }, 1200);
|
setTimeout(function(){ location.reload(); }, 1200);
|
||||||
} else {
|
} else {
|
||||||
showMemMsg(data.error || 'A művelet nem sikerült', true);
|
showMemMsg(data.error || '{{T "settings_system.a_muvelet_nem_sikerult"}}', true);
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = 'Átméretezés';
|
btn.textContent = '{{T "settings_system.atmeretezes"}}';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function() {
|
.catch(function() {
|
||||||
showMemMsg('Kapcsolódási hiba', true);
|
showMemMsg('{{T "settings_system.kapcsolodasi_hiba"}}', true);
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = 'Átméretezés';
|
btn.textContent = '{{T "settings_system.atmeretezes"}}';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function showMemMsg(text, isErr) {
|
function showMemMsg(text, isErr) {
|
||||||
@@ -357,50 +357,49 @@ pollUntilBack();
|
|||||||
|
|
||||||
<!-- Section: Controller restart (self-serve) — always available (not gated on RetrievalPassword) -->
|
<!-- Section: Controller restart (self-serve) — always available (not gated on RetrievalPassword) -->
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Vezérlő újraindítása</h3>
|
<h3>{{T "settings_system.vezerlo_ujrainditasa"}}</h3>
|
||||||
<p class="settings-card-desc">
|
<p class="settings-card-desc">
|
||||||
Ha a vezérlő hibásan működik, itt biztonságosan újraindíthatja — nem kell az egész szervert újraindítani.
|
{{T "settings_system.ha_a_vezerlo_hibasan_mukodik"}}
|
||||||
Az alkalmazásai futnak tovább; csak a vezérlő indul újra (néhány másodperc).
|
|
||||||
</p>
|
</p>
|
||||||
<div id="restart-status"></div>
|
<div id="restart-status"></div>
|
||||||
<button type="button" class="btn btn-outline" id="btn-restart-controller" onclick="restartController()">Vezérlő újraindítása</button>
|
<button type="button" class="btn btn-outline" id="btn-restart-controller" onclick="restartController()">{{T "settings_system.vezerlo_ujrainditasa"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Section: Full server (guest) restart — a deliberate maintenance affordance, sibling to the controller restart -->
|
<!-- Section: Full server (guest) restart — a deliberate maintenance affordance, sibling to the controller restart -->
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>Kiszolgáló újraindítása</h3>
|
<h3>{{T "settings_system.kiszolgalo_ujrainditasa"}}</h3>
|
||||||
<p class="settings-card-desc">
|
<p class="settings-card-desc">
|
||||||
Az egész kiszolgáló (szerver) újraindítása. Minden alkalmazás rövid időre leáll, és a vezérlőpult kb. 30 másodpercig nem elérhető. Akkor használja, ha a teljes rendszer újraindítására van szükség — egyébként a fenti „Vezérlő újraindítása” elegendő.
|
{{T "settings_system.az_egesz_kiszolgalo_szerver_ujrainditasa"}}
|
||||||
</p>
|
</p>
|
||||||
<div id="server-restart-status"></div>
|
<div id="server-restart-status"></div>
|
||||||
<button type="button" class="btn btn-outline" id="btn-restart-server" onclick="restartServer()">Kiszolgáló újraindítása</button>
|
<button type="button" class="btn btn-outline" id="btn-restart-server" onclick="restartServer()">{{T "settings_system.kiszolgalo_ujrainditasa"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function restartController() {
|
function restartController() {
|
||||||
openDialog({title:'Vezérlő újraindítása', confirmLabel:'Újraindítás',
|
openDialog({title:'{{T "settings_system.vezerlo_ujrainditasa"}}', confirmLabel:'{{T "common.ujrainditas"}}',
|
||||||
message:'Biztosan újraindítja a vezérlőt? A művelet néhány másodpercig tart, és a felület rövid időre elérhetetlen lesz.',
|
message:'{{T "settings_system.biztosan_ujrainditja_a_vezerlot_a"}}',
|
||||||
onConfirm:doRestartController});
|
onConfirm:doRestartController});
|
||||||
}
|
}
|
||||||
function doRestartController() {
|
function doRestartController() {
|
||||||
var btn = document.getElementById('btn-restart-controller');
|
var btn = document.getElementById('btn-restart-controller');
|
||||||
var status = document.getElementById('restart-status');
|
var status = document.getElementById('restart-status');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
status.innerHTML = '<div class="alert alert-info">Újraindítás folyamatban… újracsatlakozás…</div>';
|
status.innerHTML = '<div class="alert alert-info">{{T "settings_system.ujrainditas_folyamatban_ujracsatlakozas"}}</div>';
|
||||||
fetch('/api/selfrestart', { method: 'POST', headers: csrfHeaders() })
|
fetch('/api/selfrestart', { method: 'POST', headers: csrfHeaders() })
|
||||||
.then(function(){ pollRestart(0); })
|
.then(function(){ pollRestart(0); })
|
||||||
.catch(function(){ pollRestart(0); }); // connection may drop as the process exits — poll regardless
|
.catch(function(){ pollRestart(0); }); // connection may drop as the process exits — poll regardless
|
||||||
}
|
}
|
||||||
function restartServer() {
|
function restartServer() {
|
||||||
openDialog({title:'Kiszolgáló újraindítása', confirmLabel:'Újraindítás',
|
openDialog({title:'{{T "settings_system.kiszolgalo_ujrainditasa"}}', confirmLabel:'{{T "common.ujrainditas"}}',
|
||||||
message:'Biztosan újraindítja a kiszolgálót? Az alkalmazások és a vezérlőpult kb. 30 másodpercre elérhetetlenné válnak.',
|
message:'{{T "settings_system.biztosan_ujrainditja_a_kiszolgalot_az"}}',
|
||||||
onConfirm:doRestartServer});
|
onConfirm:doRestartServer});
|
||||||
}
|
}
|
||||||
function doRestartServer() {
|
function doRestartServer() {
|
||||||
var btn = document.getElementById('btn-restart-server');
|
var btn = document.getElementById('btn-restart-server');
|
||||||
var status = document.getElementById('server-restart-status');
|
var status = document.getElementById('server-restart-status');
|
||||||
if (btn) btn.disabled = true;
|
if (btn) btn.disabled = true;
|
||||||
if (status) status.innerHTML = '<div class="alert alert-info">Újraindítás folyamatban… a vezérlőpult néhány másodperc múlva újratölt.</div>';
|
if (status) status.innerHTML = '<div class="alert alert-info">{{T "settings_system.ujrainditas_folyamatban_a_vezerlopult_ne"}}</div>';
|
||||||
fetch('/api/server/reboot', { method: 'POST', headers: csrfHeaders() })
|
fetch('/api/server/reboot', { method: 'POST', headers: csrfHeaders() })
|
||||||
.then(function(){ pollRestart(0); })
|
.then(function(){ pollRestart(0); })
|
||||||
.catch(function(){ pollRestart(0); }); // the guest reboot drops the connection — poll regardless
|
.catch(function(){ pollRestart(0); }); // the guest reboot drops the connection — poll regardless
|
||||||
@@ -408,7 +407,7 @@ function doRestartServer() {
|
|||||||
function pollRestart(attempt) {
|
function pollRestart(attempt) {
|
||||||
if (attempt > 60) { // ~2 min cap — never leave the user on a dead page silently
|
if (attempt > 60) { // ~2 min cap — never leave the user on a dead page silently
|
||||||
document.getElementById('restart-status').innerHTML =
|
document.getElementById('restart-status').innerHTML =
|
||||||
'<div class="alert alert-error">Az újraindítás a vártnál tovább tart. Töltse újra az oldalt kézzel.</div>';
|
'<div class="alert alert-error">{{T "settings_system.az_ujrainditas_a_vartnal_tovabb"}}</div>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
|
|||||||
@@ -2,18 +2,18 @@
|
|||||||
{{template "layout_start" .}}
|
{{template "layout_start" .}}
|
||||||
|
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>Alkalmazások</h2>
|
<h2>{{T "stacks.alkalmazasok"}}</h2>
|
||||||
<span class="domain-badge">{{.Domain}}</span>
|
<span class="domain-badge">{{.Domain}}</span>
|
||||||
<a href="/import" class="btn btn-sm btn-outline" title="Alkalmazás visszaállítása exportált csomagból">Importálás</a>
|
<a href="/import" class="btn btn-sm btn-outline" title="{{T "stacks.alkalmazas_visszaallitasa_exportalt_csom"}}">{{T "stacks.importalas"}}</a>
|
||||||
<button class="btn btn-sm btn-outline" id="sync-btn" onclick="syncTemplates()" title="Sablonok frissítése a központi katalógusból">↻ Sablonok frissítése</button>
|
<button class="btn btn-sm btn-outline" id="sync-btn" onclick="syncTemplates()" title="{{T "stacks.sablonok_frissitese_a_kozponti_katalogus"}}">{{T "stacks.sablonok_frissitese"}}</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="sync-toast" class="sync-toast" style="display:none"></div>
|
<div id="sync-toast" class="sync-toast" style="display:none"></div>
|
||||||
|
|
||||||
<div class="filter-bar" id="filter-bar">
|
<div class="filter-bar" id="filter-bar">
|
||||||
<button class="filter-btn active" data-filter="all">Mind <span class="filter-count" id="count-all"></span></button>
|
<button class="filter-btn active" data-filter="all">{{T "stacks.mind"}} <span class="filter-count" id="count-all"></span></button>
|
||||||
<button class="filter-btn" data-filter="running">Futó <span class="filter-count" id="count-running"></span></button>
|
<button class="filter-btn" data-filter="running">{{T "stacks.futo"}} <span class="filter-count" id="count-running"></span></button>
|
||||||
<button class="filter-btn" data-filter="stopped">Leállítva <span class="filter-count" id="count-stopped"></span></button>
|
<button class="filter-btn" data-filter="stopped">{{T "stacks.leallitva"}} <span class="filter-count" id="count-stopped"></span></button>
|
||||||
<button class="filter-btn" data-filter="available">Telepíthető <span class="filter-count" id="count-available"></span></button>
|
<button class="filter-btn" data-filter="available">{{T "stacks.telepitheto"}} <span class="filter-count" id="count-available"></span></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stack-grid">
|
<div class="stack-grid">
|
||||||
@@ -32,18 +32,18 @@
|
|||||||
{{$subdomain}}.{{$.Domain}} ↗
|
{{$subdomain}}.{{$.Domain}} ↗
|
||||||
</a>
|
</a>
|
||||||
{{if and .Deployed (routeUnpublished .State)}}
|
{{if and .Deployed (routeUnpublished .State)}}
|
||||||
<span class="route-unpublished" title="A proxy (Traefik) csak egészséges konténerhez publikál nyilvános útvonalat. Amíg az alkalmazás nem egészséges, az URL nem érhető el (404), pedig a konténer fut."><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> URL nem elérhető – útvonal nincs publikálva</span>
|
<span class="route-unpublished" title="{{T "stacks.a_proxy_traefik_csak_egeszseges"}}"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg> {{T "stacks.url_nem_elerheto_utvonal_nincs"}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="tag tag-{{stateColor .State}}"><span class="dot"></span>{{stateLabel .State}}</span>
|
<span class="tag tag-{{stateColor .State}}"><span class="dot"></span>{{stateLabel .State}}</span>
|
||||||
{{if .Orphaned}}<span class="tag tag-warn">Elavult</span>{{end}}
|
{{if .Orphaned}}<span class="tag tag-warn">{{T "common.elavult"}}</span>{{end}}
|
||||||
{{template "meta_badge" (lifecycleBadge .Meta)}}
|
{{template "meta_badge" (lifecycleBadge .Meta)}}
|
||||||
{{template "meta_badge" (updateBadge .)}}
|
{{template "meta_badge" (updateBadge .)}}
|
||||||
{{$ms := index $.MissingStorage .Name}}{{if $ms}}<span class="tag tag-warn" title="Az alkalmazás adattárolója nem elérhető. Csatlakoztasd újra a meghajtót, vagy helyezd át az adatokat."><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>Hiányzó tárhely: {{$ms}}</span>{{end}}
|
{{$ms := index $.MissingStorage .Name}}{{if $ms}}<span class="tag tag-warn" title="{{T "stacks.az_alkalmazas_adattaroloja_nem_elerheto"}}"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>{{T "stacks.hianyzo_tarhely"}}</span>{{end}}
|
||||||
{{$ns := index $.NetworkStubs .Name}}{{if $ns}}<span class="tag tag-warn" title="Az alkalmazás környezetében a hálózati tárhely helyén üres helyi könyvtár van — az adatok nem a NAS-ra kerülnek. Jelezze az üzemeltetőnek."><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>Hálózati tárhely hibás — az alkalmazás nem a NAS-t látja</span>{{end}}
|
{{$ns := index $.NetworkStubs .Name}}{{if $ns}}<span class="tag tag-warn" title="{{T "stacks.az_alkalmazas_kornyezeteben_a_halozati"}}"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>{{T "stacks.halozati_tarhely_hibas_az_alkalmazas"}}</span>{{end}}
|
||||||
{{$nw := index $.NetworkWarnings .Name}}{{if $nw}}<span class="tag tag-warn" title="A hálózati tárhely (NAS) jelenleg nem érhető el. Az alkalmazás fut; az adatok elérése a NAS visszatértével helyreáll."><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>Hálózati tárhely nem elérhető: {{$nw}}</span>{{end}}
|
{{$nw := index $.NetworkWarnings .Name}}{{if $nw}}<span class="tag tag-warn" title="{{T "stacks.a_halozati_tarhely_nas_jelenleg"}}"><svg class="ico ico-sm"><use href="#i-triangle-alert"/></svg>{{T "stacks.halozati_tarhely_nem_elerheto"}}</span>{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if $im}}
|
{{if $im}}
|
||||||
@@ -54,10 +54,10 @@
|
|||||||
|
|
||||||
<div class="metarows">
|
<div class="metarows">
|
||||||
{{if .Meta.Resources.MemRequest}}<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~{{.Meta.Resources.MemRequest}}</span></span>{{end}}
|
{{if .Meta.Resources.MemRequest}}<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~{{.Meta.Resources.MemRequest}}</span></span>{{end}}
|
||||||
{{if .Meta.Resources.PiCompatible}}<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>{{end}}
|
{{if .Meta.Resources.PiCompatible}}<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>{{T "common.pi_kompatibilis"}}</span>{{end}}
|
||||||
{{if .Meta.Resources.NeedsHDD}}<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>{{end}}
|
{{if .Meta.Resources.NeedsHDD}}<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>{{T "common.hdd_szukseges"}}</span>{{end}}
|
||||||
{{if .Meta.Resources.HungarianUI}}<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Magyar felület</span>{{end}}
|
{{if .Meta.Resources.HungarianUI}}<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>{{T "common.magyar_felulet"}}</span>{{end}}
|
||||||
{{if and .Deployed (index $.StorageLabels .Name)}}<span class="metarow" title="Adattároló: {{index $.StorageLabels .Name}}"><svg class="ico"><use href="#i-hard-drive"/></svg>{{index $.StorageLabels .Name}}</span>{{end}}
|
{{if and .Deployed (index $.StorageLabels .Name)}}<span class="metarow" title="{{T "stacks.adattarolo"}}"><svg class="ico"><use href="#i-hard-drive"/></svg>{{index $.StorageLabels .Name}}</span>{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if .Containers}}
|
{{if .Containers}}
|
||||||
@@ -73,18 +73,18 @@
|
|||||||
|
|
||||||
<div class="stack-detail-actions">
|
<div class="stack-detail-actions">
|
||||||
{{if .Protected}}
|
{{if .Protected}}
|
||||||
<span class="tag"><svg class="ico ico-sm"><use href="#i-lock"/></svg>Védett rendszerkomponens</span>
|
<span class="tag"><svg class="ico ico-sm"><use href="#i-lock"/></svg>{{T "stacks.vedett_rendszerkomponens"}}</span>
|
||||||
{{if isOperational .State}}
|
{{if isOperational .State}}
|
||||||
<button class="btn btn-warning" onclick="stackAction(event, '{{.Name}}', 'restart')">Újraindítás</button>
|
<button class="btn btn-warning" onclick="stackAction(event, '{{.Name}}', 'restart')">{{T "common.ujrainditas"}}</button>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .Meta.Slug}}
|
{{if .Meta.Slug}}
|
||||||
<a href="/apps/{{.Meta.Slug}}" class="btn btn-outline">Részletek</a>
|
<a href="/apps/{{.Meta.Slug}}" class="btn btn-outline">{{T "stacks.reszletek"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else if not .Deployed}}
|
{{else if not .Deployed}}
|
||||||
{{/* The endpoint refuses a non-installable template server-side; hiding the button
|
{{/* The endpoint refuses a non-installable template server-side; hiding the button
|
||||||
here keeps the two consistent rather than offering an action that will fail. */}}
|
here keeps the two consistent rather than offering an action that will fail. */}}
|
||||||
{{if canInstall .Meta}}<a href="/stacks/{{.Name}}/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, '{{.Name}}')">Telepítés</a>{{end}}
|
{{if canInstall .Meta}}<a href="/stacks/{{.Name}}/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, '{{.Name}}')">{{T "stacks.telepites"}}</a>{{end}}
|
||||||
<a href="{{appPageURL .Meta.Slug}}" class="btn btn-outline">Részletek</a>
|
<a href="{{appPageURL .Meta.Slug}}" class="btn btn-outline">{{T "stacks.reszletek"}}</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{/* Slice 4 (v0.238.0): the UPDATING and HELD checks come BEFORE isOperational. That
|
{{/* Slice 4 (v0.238.0): the UPDATING and HELD checks come BEFORE isOperational. That
|
||||||
predicate counts `restarting` as operational, which is how the 2026-09-01 spike saw
|
predicate counts `restarting` as operational, which is how the 2026-09-01 spike saw
|
||||||
@@ -93,21 +93,21 @@
|
|||||||
{{if .Updating}}
|
{{if .Updating}}
|
||||||
<span class="tag tag-progress" data-update-phase="{{.UpdatePhase}}"><span class="dot"></span>{{.UpdatePhaseLabel}}</span>
|
<span class="tag tag-progress" data-update-phase="{{.UpdatePhase}}"><span class="dot"></span>{{.UpdatePhaseLabel}}</span>
|
||||||
{{else if .HoldReason}}
|
{{else if .HoldReason}}
|
||||||
<div class="alert alert-error" data-held="true">{{.HoldReason}} <a href="/backups/apps" class="btn btn-sm btn-outline">Mentések</a></div>
|
<div class="alert alert-error" data-held="true">{{.HoldReason}} <a href="/backups/apps" class="btn btn-sm btn-outline">{{T "stacks.mentesek"}}</a></div>
|
||||||
{{if not .Orphaned}}<button class="btn btn-danger" onclick="removeStack('{{.Name}}')">Eltávolítás</button>{{end}}
|
{{if not .Orphaned}}<button class="btn btn-danger" onclick="removeStack('{{.Name}}')">{{T "common.eltavolitas"}}</button>{{end}}
|
||||||
{{else if isOperational .State}}
|
{{else if isOperational .State}}
|
||||||
{{if .UpdateError}}<div class="alert alert-warning" data-update-error="true">{{.UpdateError}}</div>{{end}}
|
{{if .UpdateError}}<div class="alert alert-warning" data-update-error="true">{{.UpdateError}}</div>{{end}}
|
||||||
{{if not .Orphaned}}<button class="btn btn-success" onclick="stackAction(event, '{{.Name}}', 'update')">Frissítés</button>{{end}}
|
{{if not .Orphaned}}<button class="btn btn-success" onclick="stackAction(event, '{{.Name}}', 'update')">{{T "stacks.frissites"}}</button>{{end}}
|
||||||
<button class="btn btn-warning" onclick="stackAction(event, '{{.Name}}', 'restart')">Újraindítás</button>
|
<button class="btn btn-warning" onclick="stackAction(event, '{{.Name}}', 'restart')">{{T "common.ujrainditas"}}</button>
|
||||||
<button class="btn btn-danger" onclick="stackAction(event, '{{.Name}}', 'stop')">Leállítás</button>
|
<button class="btn btn-danger" onclick="stackAction(event, '{{.Name}}', 'stop')">{{T "stacks.leallitas"}}</button>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{if .UpdateError}}<div class="alert alert-warning" data-update-error="true">{{.UpdateError}}</div>{{end}}
|
{{if .UpdateError}}<div class="alert alert-warning" data-update-error="true">{{.UpdateError}}</div>{{end}}
|
||||||
<button class="btn btn-success" onclick="stackAction(event, '{{.Name}}', 'start')">Indítás</button>
|
<button class="btn btn-success" onclick="stackAction(event, '{{.Name}}', 'start')">{{T "stacks.inditas"}}</button>
|
||||||
{{if not .Orphaned}}<button class="btn btn-danger" onclick="removeStack('{{.Name}}')">Eltávolítás</button>{{end}}
|
{{if not .Orphaned}}<button class="btn btn-danger" onclick="removeStack('{{.Name}}')">{{T "common.eltavolitas"}}</button>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<a href="/stacks/{{.Name}}/logs" class="btn btn-outline">Naplók</a>
|
<a href="/stacks/{{.Name}}/logs" class="btn btn-outline">{{T "stacks.naplok"}}</a>
|
||||||
{{if not .Orphaned}}<a href="{{appPageURL .Meta.Slug}}" class="btn btn-outline">Részletek</a>{{end}}
|
{{if not .Orphaned}}<a href="{{appPageURL .Meta.Slug}}" class="btn btn-outline">{{T "stacks.reszletek"}}</a>{{end}}
|
||||||
{{if .Orphaned}}<button class="btn btn-danger" onclick="deleteOrphanStack('{{.Name}}')">Törlés</button>{{end}}
|
{{if .Orphaned}}<button class="btn btn-danger" onclick="deleteOrphanStack('{{.Name}}')">{{T "common.torles"}}</button>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ ASCII_HU = re.compile(r"\b(Fut|Nincs|Igen|Nem|Hiba|Mentve|Rendben|Adatok|Napi|He
|
|||||||
r"Perc|Letiltva|Bekapcsolva|Kikapcsolva|Folyamatban|Sikertelen|Sikeres|Tartalom|"
|
r"Perc|Letiltva|Bekapcsolva|Kikapcsolva|Folyamatban|Sikertelen|Sikeres|Tartalom|"
|
||||||
r"Kapcsolat|Vissza|Megosztva|Kezdeti|Rendszer|Csatlakozva|Kulcs|Megnyit|Elrejt|"
|
r"Kapcsolat|Vissza|Megosztva|Kezdeti|Rendszer|Csatlakozva|Kulcs|Megnyit|Elrejt|"
|
||||||
r"Ismeretlen|Szabad|Foglalt|Kijelentkezes|Napok|nap|perc|ora|"
|
r"Ismeretlen|Szabad|Foglalt|Kijelentkezes|Napok|nap|perc|ora|"
|
||||||
r"Megszakadt|Elavult|Csak|kompatibilis|Rendszermonitor|Most nem)\b", re.I)
|
r"Megszakadt|Elavult|Csak|kompatibilis|Rendszermonitor|Most nem|"
|
||||||
|
# slice 1 release A review: left behind on dashboard..settings_notifications
|
||||||
|
r"Folyamat|Titkos|Processzor|Hamarosan|aldomain|adatai|Figyelem|pelda)\b", re.I)
|
||||||
|
|
||||||
INLINE = {"strong", "em", "b", "i", "br", "code", "small", "a", "kbd", "u"} # NOT span: it is layout here
|
INLINE = {"strong", "em", "b", "i", "br", "code", "small", "a", "kbd", "u"} # NOT span: it is layout here
|
||||||
VOID = {"br"}
|
VOID = {"br"}
|
||||||
@@ -328,6 +330,14 @@ def js_edits(body, base, ctx):
|
|||||||
gt, lt = content.find(">"), content.find("<")
|
gt, lt = content.find(">"), content.find("<")
|
||||||
if gt >= 0 and (lt < 0 or gt < lt):
|
if gt >= 0 and (lt < 0 or gt < lt):
|
||||||
skip = gt + 1
|
skip = gt + 1
|
||||||
|
# ...or it starts inside an attribute value: '%;opacity:.5" title="Rendszer: ' — only the
|
||||||
|
# text after the last attribute opening is copy (slice 1 release A, monitoring.html).
|
||||||
|
elif lt < 0:
|
||||||
|
last = None
|
||||||
|
for am in re.finditer(r'=\s*"', content):
|
||||||
|
last = am
|
||||||
|
if last is not None:
|
||||||
|
skip = last.end()
|
||||||
sub = edits_for_fragment(content[skip:], base + i + 1 + skip, ctx, allow_attrs=False)
|
sub = edits_for_fragment(content[skip:], base + i + 1 + skip, ctx, allow_attrs=False)
|
||||||
ctx.stats["js"] += len(sub)
|
ctx.stats["js"] += len(sub)
|
||||||
edits.extend(sub)
|
edits.extend(sub)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ TEMPLATE_ROOTS = [os.path.join(CTRL, "internal", "web", "templates")]
|
|||||||
MARKER = re.compile(r'\{\{\s*T\s+"([A-Za-z0-9_.\-]+)"\s*\}\}')
|
MARKER = re.compile(r'\{\{\s*T\s+"([A-Za-z0-9_.\-]+)"\s*\}\}')
|
||||||
|
|
||||||
EN_MISSING_CEILING = 0
|
EN_MISSING_CEILING = 0
|
||||||
HU_FORMAL_CEILING = 6
|
HU_FORMAL_CEILING = 10 # raised 6 -> 10 in slice 1 release A: the converted pages carry 4 more (R-516), not changed (parity)
|
||||||
|
|
||||||
EN_FORBIDDEN = re.compile(r"\b(please|kindly)\b", re.I)
|
EN_FORBIDDEN = re.compile(r"\b(please|kindly)\b", re.I)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user