diff --git a/.claude/skills/pr-analysis/SKILL.md b/.claude/skills/pr-analysis/SKILL.md
index 3a17b8a88..1f97474d7 100644
--- a/.claude/skills/pr-analysis/SKILL.md
+++ b/.claude/skills/pr-analysis/SKILL.md
@@ -47,7 +47,7 @@ For each comment, determine:
1. **Identify all actionable comments** before touching any file.
2. **Load relevant skills** to understand conventions that apply.
-3. **Prepare a plan** — list each file and the exact change required.
+3. **Prepare a plan** — list each file and the exact change required. If a comment calls for new logic (a new check, helper, or condition), search for an existing equivalent first - the whole file being edited, not just the section in question, plus sibling pages/the Python backend - and extract/reuse it rather than planning a parallel implementation (see `code-standards`' DRY Principle section).
4. **Make changes one comment at a time** — keep commits focused.
5. **Run targeted tests** after each change (`testing-workflow` skill).
6. **Reply** only after the commit is pushed. Include the short SHA.
diff --git a/.claude/skills/prd-writing/SKILL.md b/.claude/skills/prd-writing/SKILL.md
index 08a539fea..85facbd2f 100644
--- a/.claude/skills/prd-writing/SKILL.md
+++ b/.claude/skills/prd-writing/SKILL.md
@@ -9,6 +9,8 @@ description: Read before writing a PRD, design doc, or feature proposal. Covers
Triggered by: "write a PRD", "draft a design doc", "spec out this feature", "create a PRD for X". Reserve this for changes where getting the design wrong is expensive to unwind — new cross-cutting mechanisms, schema changes, anything touching multiple subsystems. A one-file bug fix doesn't need this process.
+**A UI feature that needs to survive a page reload, coordinate across tabs, or react to a backend push/poll is a cross-cutting mechanism even when it looks like "just a small UI feature."** It's easy to start implementing straight away because the visible surface (a badge, an icon) looks trivial - but the hard part is always the state-propagation mechanism underneath, and that mechanism usually has hidden dependencies on other code that already touches the same data. A real case: a "settings still applying" indicator went through three full implementation-and-break cycles (a cookie with a guessed timeout, a new PHP endpoint duplicating existing logic, a `localStorage`/polling redesign with its own bugs) before anyone traced every existing consumer of `app_state.json` and found that `front/js/sse_manager.js`'s `handleStateUpdate()` already pushed the exact signal needed to every open page. Step 4 ("trace every downstream consumer") below would have caught this on attempt #1 if it had been applied before writing any code, not after three failures.
+
## Core principle: a PRD is a claim-verification exercise, not a writing exercise
Every sentence that asserts something about how the code currently works must be checked against the actual code before it goes in — not written from memory, not inferred from a plugin's name or reputation, not assumed because it sounds plausible. Two failure patterns to watch for:
diff --git a/.gemini/skills/pr-analysis/SKILL.md b/.gemini/skills/pr-analysis/SKILL.md
index edd32ba48..8202014db 100644
--- a/.gemini/skills/pr-analysis/SKILL.md
+++ b/.gemini/skills/pr-analysis/SKILL.md
@@ -47,7 +47,7 @@ For each comment, determine:
1. **Identify all actionable comments** before touching any file.
2. **Load relevant skills** to understand conventions that apply.
-3. **Prepare a plan** — list each file and the exact change required.
+3. **Prepare a plan** — list each file and the exact change required. If a comment calls for new logic (a new check, helper, or condition), search for an existing equivalent first - the whole file being edited, not just the section in question, plus sibling pages/the Python backend - and extract/reuse it rather than planning a parallel implementation (see `code-standards`' DRY Principle section).
4. **Make changes one comment at a time** — keep commits focused. For a comment claiming a bug: write the test that should catch it first, run it against the current (unfixed) code, and confirm it fails for the right reason before writing the fix - see `prd-writing`'s test-first step for why (a test that never failed red can't be trusted to have caught anything).
5. **Rerun tests after each change** (`testing-workflow` skill) - confirm the new/updated test now passes, not just that nothing else broke.
6. **Reply** only after the commit is pushed. Include the short SHA.
diff --git a/.gemini/skills/prd-writing/SKILL.md b/.gemini/skills/prd-writing/SKILL.md
index 41fdb1896..313d7b26f 100644
--- a/.gemini/skills/prd-writing/SKILL.md
+++ b/.gemini/skills/prd-writing/SKILL.md
@@ -9,6 +9,8 @@ description: Rigorous PRD-writing methodology — challenge the idea, verify eve
Triggered by: "write a PRD", "draft a design doc", "spec out this feature", "create a PRD for X". Reserve this for changes where getting the design wrong is expensive to unwind — new cross-cutting mechanisms, schema changes, anything touching multiple subsystems. A one-file bug fix doesn't need this process.
+**A UI feature that needs to survive a page reload, coordinate across tabs, or react to a backend push/poll is a cross-cutting mechanism even when it looks like "just a small UI feature."** It's easy to start implementing straight away because the visible surface (a badge, an icon) looks trivial - but the hard part is always the state-propagation mechanism underneath, and that mechanism usually has hidden dependencies on other code that already touches the same data. A real case: a "settings still applying" indicator went through three full implementation-and-break cycles (a cookie with a guessed timeout, a new PHP endpoint duplicating existing logic, a `localStorage`/polling redesign with its own bugs) before anyone traced every existing consumer of `app_state.json` and found that `front/js/sse_manager.js`'s `handleStateUpdate()` already pushed the exact signal needed to every open page. Step 4 ("trace every downstream consumer") below would have caught this on attempt #1 if it had been applied before writing any code, not after three failures.
+
## Core principle: a PRD is a claim-verification exercise, not a writing exercise
Every sentence that asserts something about how the code currently works must be checked against the actual code before it goes in — not written from memory, not inferred from a plugin's name or reputation, not assumed because it sounds plausible. Two failure patterns to watch for:
diff --git a/.github/skills/code-standards/SKILL.md b/.github/skills/code-standards/SKILL.md
index 41a1a90ba..07c7c3066 100644
--- a/.github/skills/code-standards/SKILL.md
+++ b/.github/skills/code-standards/SKILL.md
@@ -27,6 +27,7 @@ description: NetAlertX coding standards and conventions. Use this when writing c
- when using `server/logger.py` `mylog()`, only use valid levels: `none`, `minimal`, `verbose`, `debug`, `trace`; invalid levels silently degrade to `none`
- every Python function/method needs a succinct docstring describing its current use and behavior — not what changed or why (see Docstrings section below)
- before adding a new frontend language string, search `front/php/templates/language/en_us.json` for an existing key with the same text/purpose and reuse it — don't add a near-duplicate key just because it's needed on a new page (see Language Strings section below)
+- never add new server-side PHP logic (a new endpoint, new computation inside an existing PHP file) — `front/` is being migrated away from PHP, so any new backend state/computation belongs in the Python server, exposed to the frontend via an existing read path (see PHP/Python Boundary section below)
## File Length
@@ -37,6 +38,10 @@ Keep code files under 500 lines. Split larger files into modules.
Do not re-implement functionality. Reuse existing methods or refactor to create shared methods.
+**This is a required pre-step, not a cleanup pass to do later.** Before writing any new check/condition/helper, search for an existing implementation of the same or similar logic first - grep the codebase, and read the *whole* file you're already touching, not just the section being edited. If something equivalent exists, extract it into a shared function and call it from the new site instead of writing a parallel implementation.
+
+A real case this was missed on: a new frontend indicator needed to know "is the backend still applying a settings change." That exact check already existed inline in `settings.php`'s own polling loop (`handleLoadingDialog()`, further down the same file being edited) - it took two rounds of reinventing it elsewhere (a cookie-based guess, then a duplicate PHP endpoint computing the same thing a second time) before it got extracted into one shared function (`isSettingsPending()` in `common.js`) that both the original page and the new consumer call. Read the existing code first; refactor into something reusable *while* implementing, not after a reviewer points out the duplication.
+
## Database Access
- Never access DB directly from application layers
@@ -109,6 +114,26 @@ grep -n "Next\|Previous\|Showing" front/php/templates/language/en_us.json
Prefer the generic `Gen_*` keys (e.g. `Gen_Prev`, `Gen_Next`) over a page-scoped name (`Presence_Page_Prev`) for genuinely generic UI text — a future page needing the same label should find it already there. Only add a new key when nothing existing fits; only that one file needs the addition — `getString()`/`lang()` fall back to the English string for any locale missing a key, so the other ~23 locale files don't need touching.
+## PHP/Python Boundary — No New PHP Backend Logic
+
+`front/` is being migrated away from PHP. Never add a new PHP endpoint, or new server-side computation inside an existing PHP file - if a feature needs backend state or computation, it belongs in the Python server (`server/`), exposed to the frontend through an existing read path:
+
+- `app_state.json`, read via the generic `front/php/server/query_json.php` file-passthrough (no settings/state-specific logic lives in that file - it just serves raw JSON)
+- `table_settings.json` (same passthrough)
+- an existing REST or GraphQL endpoint
+
+A real case this was caught on: a new "settings still applying" UI indicator needed to know whether the backend had caught up on a config reload. The correct signal (`showSpinner` state + a config-file-mtime comparison) already existed in Python (`server/initialise.py`'s `importConfigs()`) - the first draft instead re-derived the same comparison in a new PHP endpoint, duplicating logic that the Python backend already computed and should have just exposed into existing shared state.
+
+Editing *existing* PHP page logic - templating, fixing a bug like a broken `explode()` parse, wiring up a new `
` - is fine and expected during the migration period. This rule is about not growing the PHP surface area with new backend-side logic, not about avoiding PHP entirely.
+
+## No Test Harness? Simulate Before Asking for a Live Test
+
+`front/` has no automated JS/PHP test suite. That makes it *more* important to verify a change before calling it done, not less - without a harness, "the user tests it live" becomes the only feedback loop, and that loop is slow and expensive (a real save, a real scan cycle, real timing) compared to a throwaway script.
+
+Before telling anyone a JS/PHP change is ready to test: write a small disposable Node (or PHP CLI) script that extracts the actual function(s) involved and runs them against realistic inputs - including the inputs that come from a different code path than the one being edited (a real `app_state.json` sample, a real cookie value, a renamed parameter actually being passed through). Do this on the *first* attempt, not after a live test comes back broken.
+
+A real case: a settings-reload indicator went through several rounds of "should work" before any of its logic was actually run. A standalone simulation run at that point would have immediately caught a renamed-parameter typo that a diff review missed, and an ordering bug (a cookie needing to clear before a reload fires, not inside the reload's own callback) - both found only after a live test failed, when a five-line script could have found them in seconds.
+
## Devcontainer Constraints
- Never `chmod` or `chown` during operations
diff --git a/.github/skills/pr-analysis/SKILL.md b/.github/skills/pr-analysis/SKILL.md
index 0a9c37da5..a9aaa2513 100644
--- a/.github/skills/pr-analysis/SKILL.md
+++ b/.github/skills/pr-analysis/SKILL.md
@@ -47,7 +47,7 @@ For each comment, determine:
1. **Identify all actionable comments** before touching any file.
2. **Load relevant skills** to understand conventions that apply.
-3. **Prepare a plan** — list each file and the exact change required.
+3. **Prepare a plan** — list each file and the exact change required. If a comment calls for new logic (a new check, helper, or condition), search for an existing equivalent first - the whole file being edited, not just the section in question, plus sibling pages/the Python backend - and extract/reuse it rather than planning a parallel implementation (see `code-standards`' DRY Principle section).
4. **Make changes one comment at a time** — keep commits focused. For a comment claiming a bug: write the test that should catch it first, run it against the current (unfixed) code, and confirm it fails for the right reason before writing the fix - see `prd-writing`'s test-first step for why (a test that never failed red can't be trusted to have caught anything).
5. **Rerun tests after each change** (`testing-workflow` skill) - confirm the new/updated test now passes, not just that nothing else broke.
6. **Reply** only after the commit is pushed via `report_progress`. Include the short SHA.
diff --git a/.github/skills/prd-writing/SKILL.md b/.github/skills/prd-writing/SKILL.md
index c0fbdbe76..f74c3cc15 100644
--- a/.github/skills/prd-writing/SKILL.md
+++ b/.github/skills/prd-writing/SKILL.md
@@ -9,6 +9,8 @@ description: Rigorous PRD-writing methodology for NetAlertX — challenge the id
Triggered by: "write a PRD", "draft a design doc", "spec out this feature", "create a PRD for X". Reserve this for changes where getting the design wrong is expensive to unwind — new cross-cutting mechanisms, schema changes, anything touching multiple subsystems. A one-file bug fix doesn't need this process.
+**A UI feature that needs to survive a page reload, coordinate across tabs, or react to a backend push/poll is a cross-cutting mechanism even when it looks like "just a small UI feature."** It's easy to start implementing straight away because the visible surface (a badge, an icon) looks trivial - but the hard part is always the state-propagation mechanism underneath, and that mechanism usually has hidden dependencies on other code that already touches the same data. A real case: a "settings still applying" indicator went through three full implementation-and-break cycles (a cookie with a guessed timeout, a new PHP endpoint duplicating existing logic, a `localStorage`/polling redesign with its own bugs) before anyone traced every existing consumer of `app_state.json` and found that `front/js/sse_manager.js`'s `handleStateUpdate()` already pushed the exact signal needed to every open page. Step 4 ("trace every downstream consumer") below would have caught this on attempt #1 if it had been applied before writing any code, not after three failures.
+
## Core principle: a PRD is a claim-verification exercise, not a writing exercise
Every sentence that asserts something about how the code currently works must be checked against the actual code before it goes in — not written from memory, not inferred from a plugin's name or reputation, not assumed because it sounds plausible. Two failure patterns to watch for:
diff --git a/CLAUDE.md b/CLAUDE.md
index 87c774b29..e36b7ea20 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -91,3 +91,7 @@ Procedural/how-to knowledge (running tests, resetting the DB, devcontainer manag
- Keep files under ~500 lines; split rather than grow.
- Every Python function/method gets a succinct docstring describing its current use and behavior — one or two sentences, not a changelog of what changed or why (that belongs in the commit/PR, not the docstring). Same rule for JS: a JSDoc `/** ... */` block, not a plain `//` line above the function. Whenever you touch a function that only has a plain description comment (Python or JS), convert it to a proper docstring as part of that edit rather than leaving the old style next to new code.
- Before adding a new key to `front/php/templates/language/en_us.json`, search it for an existing key with the same text/purpose and reuse it - prefer generic `Gen_*` keys over page-scoped names for genuinely generic UI text (e.g. `Gen_Prev`/`Gen_Next`, not `Presence_Page_Prev`). Only the English file needs a real translation; other locales fall back to it automatically at runtime for a key they don't have. After adding or changing any key in `en_us.json`, run `python3 front/php/templates/language/merge_translations.py` (plain stdlib, no deps) - it re-sorts `en_us.json` alphabetically and propagates the new key into every other locale file with an empty placeholder value, so translators see what needs translating. Skipping this leaves the other 23 locale files out of sync with `en_us.json`'s key set.
+- **Search before you build.** Before writing a new check/condition/helper for something (an "is X true" computation, a UI state signal, a utility), search the codebase for an existing implementation of the same or similar logic first - the same file (read the whole file, not just the section being edited), a sibling page, the Python backend. If one exists, extract it into a shared function and call it from the new site; don't write a parallel implementation planning to deduplicate later. A real case: a new frontend indicator needed to know "is the backend still applying a settings change" - that exact check already existed inline in `settings.php`'s own polling loop (`handleLoadingDialog()`), found only after two rounds of reinventing it elsewhere (a cookie-based guess, then a duplicate PHP endpoint) instead of reading the rest of the file first.
+- **No new PHP backend logic.** `front/` is being migrated away from PHP, so never add a new PHP endpoint or new server-side computation inside an existing PHP file. If a feature needs backend state or computation, add it to the Python server and expose it to the frontend through an existing read path (`app_state.json` via `query_json.php`, `table_settings.json`, a REST/GraphQL endpoint) - never re-derive logic in PHP that the Python side already knows or could easily expose. Editing existing PHP page logic (templating, bug fixes) is fine; this is about not growing the PHP surface area.
+- **A stateful UI feature (survives a reload, coordinates across tabs, reacts to a backend push) is a cross-cutting mechanism, not "just a UI feature."** Treat it like one before writing code: trace every existing consumer of the data it needs (e.g. everything that already reads `app_state.json`), not just the one file being edited. The visible surface looking small (a badge, an icon) says nothing about whether the state-propagation mechanism underneath already exists elsewhere.
+- **No JS/PHP test harness exists in `front/` — simulate before asking for a live test, every time, not after a live test fails.** Write a disposable Node/PHP script that runs the actual function(s) against realistic inputs (including inputs crossing from a different file than the one being edited) before calling a change ready to test. A diff review misses things a five-second script run catches - a renamed parameter still referenced by its old name, an ordering assumption that's wrong once two async steps are both in play.
diff --git a/front/css/app.css b/front/css/app.css
index fdc2afbfc..739c47726 100755
--- a/front/css/app.css
+++ b/front/css/app.css
@@ -1604,6 +1604,26 @@ textarea[readonly],
font-size: smaller;
}
+.main-header .sidebar-toggle
+{
+ /* .nav-pending-dot below needs a positioned ancestor to anchor to -
+ .sidebar-toggle has none by default (AdminLTE.css only sets float:left),
+ so without this it escapes to the nearest positioned element elsewhere
+ on the page instead of sitting on the toggle icon itself. */
+ position: relative;
+}
+
+.nav-pending-dot
+{
+ position: absolute;
+ top: 14px;
+ right: 10px;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ display: inline-block;
+}
+
.drag
{
cursor: move; /* fallback if grab cursor is unsupported */
diff --git a/front/js/common.js b/front/js/common.js
index b6d763c7e..0e6fa49c1 100755
--- a/front/js/common.js
+++ b/front/js/common.js
@@ -902,6 +902,41 @@ function isRandomMAC(mac)
// getDevDataByMac, cacheDevices, devicesListAll_JSON moved to cache.js
+// -----------------------------------------------------------------------------
+/**
+ * Returns true if the backend hasn't yet confirmed importing settings as
+ * recent as referenceTimeMs (appState.settingsImported, from app_state.json).
+ * No fixed timeout: server/__main__.py's main loop only calls importConfigs()
+ * at the top of each iteration, and a full scan cycle (every plugin,
+ * potentially tens of thousands of objects) can legitimately take minutes,
+ * so this stays pending for exactly as long as the backend actually takes.
+ * Used by settings.php's own handleLoadingDialog(), passing the config
+ * file's mtime*1000 (via PHP's filemtime()) as referenceTimeMs - that page's
+ * own full-page blocking spinner, unrelated to the settingsPendingReload
+ * nav indicator (handle_pending_settings.js / sse_manager.js), which doesn't
+ * need a reference time at all since its resolution is pushed via SSE.
+ * @param {object} appState - parsed app_state.json.
+ * @param {number} referenceTimeMs - a moment (ms since epoch) that should
+ * already be reflected in settingsImported if the backend has caught up.
+ * @returns {boolean}
+ */
+function isSettingsPending(appState, referenceTimeMs) {
+ var importedMs = parseInt(appState["settingsImported"] * 1000, 10);
+ return referenceTimeMs > importedMs;
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Shows/hides the sidebar-toggle's attention dot based on whether any
+ * .info-icon-nav badge in the sidebar is currently visible (not .myhidden) -
+ * deliberately doesn't know which badge triggered it, so a future badge
+ * lights this dot up for free without this function needing to change.
+ */
+function updateNavPendingDot() {
+ var anyVisible = $('.info-icon-nav').not('.myhidden').length > 0;
+ $('#navPendingDot').toggleClass('myhidden', !anyVisible);
+}
+
// -----------------------------------------------------------------------------
function isEmpty(value)
{
diff --git a/front/js/handle_pending_settings.js b/front/js/handle_pending_settings.js
new file mode 100644
index 000000000..4ff6d4d8f
--- /dev/null
+++ b/front/js/handle_pending_settings.js
@@ -0,0 +1,14 @@
+//--------------------------------------------------------------
+// Show the "settings still applying" indicator on page load if a save left
+// the settingsPendingReload cookie set (front/settings.php's save handler).
+// No polling: resolution is pushed via SSE and handled entirely in
+// sse_manager.js's handleStateUpdate() (step 4), which clears this same
+// cookie the moment appState.settingsImported confirms the import landed.
+function settingsPendingUpdateUI() {
+ var isPending = getCookie("settingsPendingReload") === "true";
+
+ $('#settingsPendingReload').toggleClass('myhidden', !isPending);
+ updateNavPendingDot();
+}
+
+settingsPendingUpdateUI();
diff --git a/front/js/handle_version.js b/front/js/handle_version.js
index 01b3eb607..24bda4afa 100755
--- a/front/js/handle_version.js
+++ b/front/js/handle_version.js
@@ -21,13 +21,15 @@ function versionUpdateUI(){
maintenanceDiv = $('#current-version-text')
}
- // handling the maintenance section message
+ // handling the maintenance section message
if(emptyArr.includes(maintenanceDiv) == false && $(maintenanceDiv).length != 0)
- {
+ {
$(maintenanceDiv).attr("class", $(maintenanceDiv).attr("class").replace("myhidden", ""))
- }
+ }
-}
+ updateNavPendingDot();
+
+}
//--------------------------------------------------------------
// Checks if a new version is available via the global app_state.json
diff --git a/front/js/sse_manager.js b/front/js/sse_manager.js
index c8536a2a5..211e8c6a2 100644
--- a/front/js/sse_manager.js
+++ b/front/js/sse_manager.js
@@ -170,6 +170,14 @@ class NetAlertXStateManager {
const importedMs = parseInt(appState["settingsImported"] * 1000);
const lastReloaded = parseInt(getCache(CACHE_KEYS.INIT_TIMESTAMP));
if (importedMs > lastReloaded) {
+ // Clear the settings-pending indicator (cookie + DOM) synchronously,
+ // before scheduling the reload below - not inside clearCache()'s own
+ // timeout. Otherwise the freshly-reloaded page would briefly re-read
+ // the still-present cookie and flash the indicator back on.
+ setCookie("settingsPendingReload", "", -1);
+ $('#settingsPendingReload').addClass('myhidden');
+ updateNavPendingDot();
+
console.log("[NetAlertX State] Settings changed — clearing cache and reloading");
setTimeout(() => clearCache(), 500);
}
diff --git a/front/php/templates/footer.php b/front/php/templates/footer.php
index dc6998772..3161cdea9 100755
--- a/front/php/templates/footer.php
+++ b/front/php/templates/footer.php
@@ -56,7 +56,8 @@
-
+
+
diff --git a/front/php/templates/header.php b/front/php/templates/header.php
index 481764115..8d85a5b65 100755
--- a/front/php/templates/header.php
+++ b/front/php/templates/header.php
@@ -185,6 +185,10 @@
+
+
@@ -402,6 +406,10 @@
L'última notificació es mostra en el seu lloc. La notificació perduda té el següent GUID:",
@@ -841,6 +842,7 @@
"settings_other_scanners": "Uns altres plugins no relacionats amb dispositius que estan actualment activats.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Altres escàners",
+ "settings_pending_reload": "",
"settings_publishers": "Altres passarel·les de notificació i edició que enviaran una notificació en funció de la configuració.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "Carregar més Editors amb la configuració LOADED_PLUGINS",
@@ -852,4 +854,4 @@
"settings_system_label": "Sistema",
"settings_update_item_warning": "Actualitza el valor sota. Sigues curós de seguir el format anterior. No hi ha validació.",
"test_event_tooltip": "Deseu els canvis primer abans de comprovar la configuració."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/cs_cz.json b/front/php/templates/language/cs_cz.json
index 8fd37258d..a71d7067d 100644
--- a/front/php/templates/language/cs_cz.json
+++ b/front/php/templates/language/cs_cz.json
@@ -817,6 +817,7 @@
"general_event_title": "Vykonávání jednorázové události",
"go_to_device_event_tooltip": "Přejít na zařízení",
"go_to_node_event_tooltip": "Přejít na stránku Síť daného uzlu",
+ "nav_pending_dot": "",
"new_version_available": "Je k dispozici nová verze.",
"report_guid": "Guid notifikace:",
"report_guid_missing": "Odkazovaná notifikace nenalezena. Je zde drobná prodleva mezi právě zaslanými notifikacemi a jejich viditelností. Znovunačtěte stránka za několik sekund. Je také možné, že vybraná notifikace byla mezitím smazána při údržbě, jak je specifikováno v nastavení DBCLNP_NOTIFI_HIST.
Namísto toho je zobrazena nejnovější notifikace. Chybějící notifikace má následující GUID:",
@@ -841,6 +842,7 @@
"settings_other_scanners": "Ostatní v tuto chvíli zapnuté zásuvné moduly, které nejsou skenery zařízení.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Ostatní skenery",
+ "settings_pending_reload": "",
"settings_publishers": "Zapnuté brány notifikací – vydavatelé, kteří odešlou notifikaci na základě vašich nastavení.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "Načíst další Vydavatele pomocí nastavení LOADED_PLUGINS",
diff --git a/front/php/templates/language/de_de.json b/front/php/templates/language/de_de.json
index 37d29bfd4..488a64178 100644
--- a/front/php/templates/language/de_de.json
+++ b/front/php/templates/language/de_de.json
@@ -890,6 +890,7 @@
"general_event_title": "",
"go_to_device_event_tooltip": "Zum Gerät navigieren",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "Es ist eine neue Version verfügbar.",
"report_guid": "",
"report_guid_missing": "",
@@ -914,6 +915,7 @@
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "Andere Scanner",
+ "settings_pending_reload": "",
"settings_publishers": "",
"settings_publishers_icon": "",
"settings_publishers_info": "Lade mehr Veröffentlicher mit den geladene Plugins-Einstellungen",
@@ -925,4 +927,4 @@
"settings_system_label": "System",
"settings_update_item_warning": "",
"test_event_tooltip": "Speichere die Änderungen, bevor Sie die Einstellungen testen."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/en_us.json b/front/php/templates/language/en_us.json
index 93d1e7422..095fc7b75 100755
--- a/front/php/templates/language/en_us.json
+++ b/front/php/templates/language/en_us.json
@@ -817,6 +817,7 @@
"general_event_title": "Executing an ad-hoc event",
"go_to_device_event_tooltip": "Navigate to the device",
"go_to_node_event_tooltip": "Navigate to the Network page of the given node",
+ "nav_pending_dot": "There are some in-menu notifications shown.",
"new_version_available": "A new version is available.",
"report_guid": "Notification guid:",
"report_guid_missing": "Linked notification not found. There is a small delay between recently sent notifications and them being available. Referesh your page and cache after a few seconds. It's also possible the selected notification have been deleted during maintenance as specified in the DBCLNP_NOTIFI_HIST setting.
The latest notification is displayed instead. The missing notification has the following GUID:",
@@ -841,6 +842,7 @@
"settings_other_scanners": "Other, non-device scanner plugins that are currently enabled.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Other scanners",
+ "settings_pending_reload": "Settings saved - the backend is still applying them, this usually takes some time depending on background scans.",
"settings_publishers": "Enabled notification gateways - publishers, that will send a notification depending on your settings.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "Load more Publishers with the LOADED_PLUGINS setting",
diff --git a/front/php/templates/language/es_es.json b/front/php/templates/language/es_es.json
index 402688567..00b84fbe8 100644
--- a/front/php/templates/language/es_es.json
+++ b/front/php/templates/language/es_es.json
@@ -888,6 +888,7 @@
"general_event_title": "Ejecutar un evento ad-hoc",
"go_to_device_event_tooltip": "Navegar al dispositivo",
"go_to_node_event_tooltip": "Vaya a la página de Red del nodo indicado",
+ "nav_pending_dot": "",
"new_version_available": "Una nueva versión está disponible.",
"report_guid": "Guía de las notificaciones:",
"report_guid_missing": "No se ha encontrado la notificación vinculada. Hay un pequeño retraso entre las notificaciones enviadas recientemente y su disponibilidad. Actualiza tu página y la caché después de unos segundos. También es posible que la notificación seleccionada se haya eliminado durante el mantenimiento, tal y como se especifica en la configuración de DBCLNP_NOTIFI_HIST.
En su lugar, se muestra la notificación más reciente. La notificación que falta tiene el siguiente GUID:",
@@ -912,6 +913,7 @@
"settings_other_scanners": "Otros plugins de escáner no relacionados con dispositivos que están activados actualmente.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Otros escáneres",
+ "settings_pending_reload": "",
"settings_publishers": "Puertas de enlace para las notificación habilitadas: editores, que enviarán una notificación según su configuración.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "Cargue más editor@s con el ajuste LOADED_PLUGINS",
@@ -923,4 +925,4 @@
"settings_system_label": "Sistema",
"settings_update_item_warning": "Actualice el valor a continuación. Tenga cuidado de seguir el formato anterior. O la validación no se realiza.",
"test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/fa_fa.json b/front/php/templates/language/fa_fa.json
index c12073226..d73ed0a35 100644
--- a/front/php/templates/language/fa_fa.json
+++ b/front/php/templates/language/fa_fa.json
@@ -817,6 +817,7 @@
"general_event_title": "",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "",
"report_guid": "",
"report_guid_missing": "",
@@ -841,6 +842,7 @@
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "",
+ "settings_pending_reload": "",
"settings_publishers": "",
"settings_publishers_icon": "",
"settings_publishers_info": "",
diff --git a/front/php/templates/language/fi_fi.json b/front/php/templates/language/fi_fi.json
index e27e3e250..3a1263454 100644
--- a/front/php/templates/language/fi_fi.json
+++ b/front/php/templates/language/fi_fi.json
@@ -817,6 +817,7 @@
"general_event_title": "",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "",
"report_guid": "",
"report_guid_missing": "",
@@ -841,6 +842,7 @@
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "",
+ "settings_pending_reload": "",
"settings_publishers": "",
"settings_publishers_icon": "",
"settings_publishers_info": "",
diff --git a/front/php/templates/language/fr_fr.json b/front/php/templates/language/fr_fr.json
index c48a13620..5e356eec2 100644
--- a/front/php/templates/language/fr_fr.json
+++ b/front/php/templates/language/fr_fr.json
@@ -817,6 +817,7 @@
"general_event_title": "Lancement d'un événement sur mesure",
"go_to_device_event_tooltip": "Naviguer vers cet appareil",
"go_to_node_event_tooltip": "Aller vers la page Réseau du nœud concerné",
+ "nav_pending_dot": "",
"new_version_available": "Une nouvelle version est disponible.",
"report_guid": "GUID de la notification :",
"report_guid_missing": "La notification associée n'a pas été trouvée. Un petit délai existe entre l'envoi d'une notification et sa disponibilité réelle pour affichage. Rafraichissez la page et votre cache après quelques secondes. Il est aussi possible que la notification sélectionnée ait été supprimée durant une opération de maintenance, comme renseigné dans le paramètre DBCLNP_NOTIFI_HIST.
La dernière notification est affichée à sa place. La notification manquante dispose du GUID suivant :",
@@ -841,6 +842,7 @@
"settings_other_scanners": "Autres plugins activés, hors scanners d'appareils.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Autres scanners",
+ "settings_pending_reload": "",
"settings_publishers": "Activer les passerelles de publication de notifications, qui enverront une notification en fonction de vos paramètres renseignés.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "Charger plus de passerelles de publication avec le paramètre LOADED_PLUGINS",
@@ -852,4 +854,4 @@
"settings_system_label": "Système",
"settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. Il n'y a pas de pas de contrôle.",
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/he_il.json b/front/php/templates/language/he_il.json
index e27e3e250..3a1263454 100644
--- a/front/php/templates/language/he_il.json
+++ b/front/php/templates/language/he_il.json
@@ -817,6 +817,7 @@
"general_event_title": "",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "",
"report_guid": "",
"report_guid_missing": "",
@@ -841,6 +842,7 @@
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "",
+ "settings_pending_reload": "",
"settings_publishers": "",
"settings_publishers_icon": "",
"settings_publishers_info": "",
diff --git a/front/php/templates/language/hu_hu.json b/front/php/templates/language/hu_hu.json
index e27e3e250..3a1263454 100644
--- a/front/php/templates/language/hu_hu.json
+++ b/front/php/templates/language/hu_hu.json
@@ -817,6 +817,7 @@
"general_event_title": "",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "",
"report_guid": "",
"report_guid_missing": "",
@@ -841,6 +842,7 @@
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "",
+ "settings_pending_reload": "",
"settings_publishers": "",
"settings_publishers_icon": "",
"settings_publishers_info": "",
diff --git a/front/php/templates/language/id_id.json b/front/php/templates/language/id_id.json
index e27e3e250..3a1263454 100644
--- a/front/php/templates/language/id_id.json
+++ b/front/php/templates/language/id_id.json
@@ -817,6 +817,7 @@
"general_event_title": "",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "",
"report_guid": "",
"report_guid_missing": "",
@@ -841,6 +842,7 @@
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "",
+ "settings_pending_reload": "",
"settings_publishers": "",
"settings_publishers_icon": "",
"settings_publishers_info": "",
diff --git a/front/php/templates/language/it_it.json b/front/php/templates/language/it_it.json
index 45d0cabb1..50694bae0 100644
--- a/front/php/templates/language/it_it.json
+++ b/front/php/templates/language/it_it.json
@@ -817,6 +817,7 @@
"general_event_title": "Esecuzione di un evento ad-hoc",
"go_to_device_event_tooltip": "Naviga al dispositivo",
"go_to_node_event_tooltip": "Passa alla pagina Rete del nodo specificato",
+ "nav_pending_dot": "",
"new_version_available": "È disponibile una nuova versione.",
"report_guid": "GUID notifica:",
"report_guid_missing": "Notifica collegata non trovata. C'è un piccolo ritardo tra la disponibilità delle notifiche inviate di recente e la loro disponibilità. Aggiorna la pagina e la cache dopo alcuni secondi. È anche possibile che la notifica selezionata sia stata eliminata durante la manutenzione come specificato nell'impostazione DBCLNP_NOTIFI_HIST.
Viene invece visualizzata l'ultima notifica. La notifica mancante ha il seguente GUID:",
@@ -841,6 +842,7 @@
"settings_other_scanners": "Altri plugin, non scanner per dispositivi, che sono attualmente abilitati.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Altri scanner",
+ "settings_pending_reload": "",
"settings_publishers": "Gateway/editori di notifica abilitati, che invieranno una notifica in base alle tue impostazioni.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "Carica più editori con l'impostazione LOADED_PLUGINS",
@@ -852,4 +854,4 @@
"settings_system_label": "Sistema",
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. La convalida non viene eseguita.",
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
-}
+}
\ No newline at end of file
diff --git a/front/php/templates/language/ja_jp.json b/front/php/templates/language/ja_jp.json
index bc61e88d0..fca4b18e6 100644
--- a/front/php/templates/language/ja_jp.json
+++ b/front/php/templates/language/ja_jp.json
@@ -817,6 +817,7 @@
"general_event_title": "アドホックイベントの実行",
"go_to_device_event_tooltip": "デバイスに移動",
"go_to_node_event_tooltip": "指定されたノードのネットワークページに移動する",
+ "nav_pending_dot": "",
"new_version_available": "新しいバージョンが利用可能です。",
"report_guid": "通知guid:",
"report_guid_missing": "リンクされた通知が見つかりません。送信された通知が利用可能になるまで、わずかな遅延が生じます。数秒後にページとキャッシュを更新してください。また、DBCLNP_NOTIFI_HIST 設定で指定されているメンテナンス中に、選択した通知が削除された可能性もあります。
代わりに最新の通知が表示されます。欠落している通知のGUIDは以下の通りです:",
@@ -841,6 +842,7 @@
"settings_other_scanners": "現在有効になっている、デバイス以外のスキャナープラグイン。",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "その他のスキャナー",
+ "settings_pending_reload": "",
"settings_publishers": "有効化された通知ゲートウェイ - 設定に応じて通知を送信する発行元。",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "LOADED_PLUGINS 設定でさらに多くのパブリッシャーを読み込みます",
diff --git a/front/php/templates/language/nb_no.json b/front/php/templates/language/nb_no.json
index 5f951ca99..e7736b043 100644
--- a/front/php/templates/language/nb_no.json
+++ b/front/php/templates/language/nb_no.json
@@ -817,6 +817,7 @@
"general_event_title": "Utfører en ad-hoc hendelse",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "",
"report_guid": "Notifikasjons GUID:",
"report_guid_missing": "Koblet notifikasjon ikke funnet. Det er en liten forsinkelse mellom nylig sendt notifikasjoner og at de er tilgjengelige. Oppdater siden din og hurtigbufferen etter noen sekunder. Det er også mulig den valgte notifikasjonen er slettet under vedlikehold som spesifisert i DBCLNP_NOTIFI_HIST innstillingen.
Den siste notifikasjonen vises i stedet. Den manglende notifikasjonen har følgende GUID:",
@@ -841,6 +842,7 @@
"settings_other_scanners": "Andre ikke enheter-plugins som er aktivert.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Andre skannere",
+ "settings_pending_reload": "",
"settings_publishers": "Aktivert notifikasjons-gateways - utgivere, som vil sende en notifikasjon avhengig av innstillingene dine.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "",
diff --git a/front/php/templates/language/pl_pl.json b/front/php/templates/language/pl_pl.json
index 06e966ecc..5bb9ff960 100644
--- a/front/php/templates/language/pl_pl.json
+++ b/front/php/templates/language/pl_pl.json
@@ -817,6 +817,7 @@
"general_event_title": "Wykonywanie zdarzenia ad-hoc",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "Przejdź do strony Sieć danego węzła",
+ "nav_pending_dot": "",
"new_version_available": "Dostępna jest nowa wersja.",
"report_guid": "GUID powiadomienia:",
"report_guid_missing": "Nie znaleziono powiązanego powiadomienia. Istnieje niewielkie opóźnienie między momentem wysłania powiadomienia a jego dostępnością. Odśwież stronę i pamięć podręczną po kilku sekundach. Możliwe również, że wybrane powiadomienie zostało usunięte podczas konserwacji, zgodnie z ustawieniem DBCLNP_NOTIFI_HIST.
Zamiast tego wyświetlane jest najnowsze powiadomienie. Brakujące powiadomienie ma następujący identyfikator GUID:",
@@ -841,6 +842,7 @@
"settings_other_scanners": "Inne, niebędące skanerami urządzeń wtyczki, które są obecnie włączone.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Inne skanery",
+ "settings_pending_reload": "",
"settings_publishers": "Włączone bramki powiadomień – publikatory, które będą wysyłać powiadomienia w zależności od twoich ustawień.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "Załaduj więcej publikatorów za pomocą ustawienia LOADED_PLUGINS",
diff --git a/front/php/templates/language/pt_br.json b/front/php/templates/language/pt_br.json
index 307d35592..aa337b138 100644
--- a/front/php/templates/language/pt_br.json
+++ b/front/php/templates/language/pt_br.json
@@ -817,6 +817,7 @@
"general_event_title": "",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "",
"report_guid": "",
"report_guid_missing": "",
@@ -841,6 +842,7 @@
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "",
+ "settings_pending_reload": "",
"settings_publishers": "",
"settings_publishers_icon": "",
"settings_publishers_info": "",
diff --git a/front/php/templates/language/pt_pt.json b/front/php/templates/language/pt_pt.json
index e4e55b06b..86bfc5292 100644
--- a/front/php/templates/language/pt_pt.json
+++ b/front/php/templates/language/pt_pt.json
@@ -817,6 +817,7 @@
"general_event_title": "A executar um evento ad-hoc",
"go_to_device_event_tooltip": "Navegar para o dispositivo",
"go_to_node_event_tooltip": "Navegar para a página de Rede do nó em questão",
+ "nav_pending_dot": "",
"new_version_available": "Uma versão nova está disponível.",
"report_guid": "Guid de Notificação:",
"report_guid_missing": "Notificação associada não foi encontrada. Há um pequeno atraso entre notificações recentemente enviadas e as mesmas estarem disponíveis. Atualize a sua página e cache após alguns segundos. Também é possível que a notificação selecionada tenha sido eliminada durante a manutenção como especificado na definição DBCLNP_NOTIFI_HIST.
Em vez disso, a última notificação é mostrada. A notificação em falta tem o seguinte GUID:",
@@ -841,6 +842,7 @@
"settings_other_scanners": "Outros plugins de scaneadores que não são do dispositivo estão atualmente ativos.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Outros scaneadores",
+ "settings_pending_reload": "",
"settings_publishers": "Gateways de notificação ativados - editores que enviarão uma notificação de acordo com as suas definições.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "Carregar mais Editores com a definição LOADED_PLUGINS",
diff --git a/front/php/templates/language/ru_ru.json b/front/php/templates/language/ru_ru.json
index 84c199428..edda373df 100644
--- a/front/php/templates/language/ru_ru.json
+++ b/front/php/templates/language/ru_ru.json
@@ -817,6 +817,7 @@
"general_event_title": "Выполнение специального события",
"go_to_device_event_tooltip": "Перейти к устройству",
"go_to_node_event_tooltip": "Переход на страницу \"Сеть\" данного узла",
+ "nav_pending_dot": "",
"new_version_available": "Доступна новая версия.",
"report_guid": "Идентификатор уведомления:",
"report_guid_missing": "Связанное уведомление не найдено. Между недавно отправленными уведомлениями и их доступностью существует небольшая задержка. Обновите страницу и кэшируйте ее через несколько секунд. Также возможно, что выбранное уведомление было удалено во время обслуживания, как указано в настройке DBCLNP_NOTIFI_HIST.
Вместо этого отображается последнее уведомление. Отсутствующее уведомление имеет следующий GUID:",
@@ -841,6 +842,7 @@
"settings_other_scanners": "Другие плагины сканера, не относящиеся к устройствам, которые в настоящее время включены.",
"settings_other_scanners_icon": "fa-solid fa-recycle",
"settings_other_scanners_label": "Другие сканеры",
+ "settings_pending_reload": "",
"settings_publishers": "Включенные шлюзы уведомлений - сервисы, которые будут отправлять уведомления в зависимости от ваших настроек.",
"settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "Загрузите больше нотификаторов с помощью настройки LOADED_PLUGINS",
diff --git a/front/php/templates/language/sv_sv.json b/front/php/templates/language/sv_sv.json
index e27e3e250..3a1263454 100644
--- a/front/php/templates/language/sv_sv.json
+++ b/front/php/templates/language/sv_sv.json
@@ -817,6 +817,7 @@
"general_event_title": "",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "",
"report_guid": "",
"report_guid_missing": "",
@@ -841,6 +842,7 @@
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "",
+ "settings_pending_reload": "",
"settings_publishers": "",
"settings_publishers_icon": "",
"settings_publishers_info": "",
diff --git a/front/php/templates/language/tr_tr.json b/front/php/templates/language/tr_tr.json
index 5ac870753..a48e6dc6c 100644
--- a/front/php/templates/language/tr_tr.json
+++ b/front/php/templates/language/tr_tr.json
@@ -817,6 +817,7 @@
"general_event_title": "",
"go_to_device_event_tooltip": "",
"go_to_node_event_tooltip": "",
+ "nav_pending_dot": "",
"new_version_available": "",
"report_guid": "",
"report_guid_missing": "",
@@ -841,6 +842,7 @@
"settings_other_scanners": "",
"settings_other_scanners_icon": "",
"settings_other_scanners_label": "Diğer tarayıcılar",
+ "settings_pending_reload": "",
"settings_publishers": "",
"settings_publishers_icon": "",
"settings_publishers_info": "",
diff --git a/front/php/templates/language/uk_ua.json b/front/php/templates/language/uk_ua.json
index ec10abf90..639d7f425 100644
--- a/front/php/templates/language/uk_ua.json
+++ b/front/php/templates/language/uk_ua.json
@@ -817,6 +817,7 @@
"general_event_title": "Виконання спеціальної події",
"go_to_device_event_tooltip": "Перейдіть до пристрою",
"go_to_node_event_tooltip": "Перейдіть на сторінку Мережа даного вузла",
+ "nav_pending_dot": "",
"new_version_available": "Доступна нова версія.",
"report_guid": "Довідник сповіщень:",
"report_guid_missing": "Пов’язане сповіщення не знайдено. Існує невелика затримка між нещодавно надісланими сповіщеннями та їх доступністю. Оновіть сторінку та кеш через кілька секунд. Також можливо, вибране сповіщення було видалено під час обслуговування, як зазначено в параметрі DBCLNP_NOTIFI_HIST.