Skip to content

Next release#1690

Open
jokob-sk wants to merge 3 commits into
mainfrom
next_release
Open

Next release#1690
jokob-sk wants to merge 3 commits into
mainfrom
next_release

Conversation

@jokob-sk

@jokob-sk jokob-sk commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added a new tools tab loading “skeleton” to enhance the tools page loading experience.
    • Enhanced loading spinners with smarter automatic targeting (uses the active/visible spinner target area when available).
  • Bug Fixes

    • Localized first/last seen timestamps consistently across device, network tree, and hover/details views.
    • Standardized light-gray foreground styling across dark themes for more consistent text appearance.
  • Improvements

    • Improved loading placeholders on device-related pages by showing skeletons earlier and keeping them reusable (fade + hide behavior) instead of removing them.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds a shared light-gray theme token, updates dark-theme text colors to use it, makes skeleton loading elements reusable spinner targets, wires spinner/skeleton behavior into device pages, and stores localized timestamps in rendered device link attributes.

Changes

UI theme, loading skeletons, and link timestamps

Layer / File(s) Summary
Light-gray theme variables
front/css/app.css, front/css/dark-patch.css, front/css/system-dark-patch.css
Adds --color-lightgray to the base and dark-theme variable sets and removes the trailing dark-theme skeleton variable block.
Dark-theme text colors
front/css/dark-patch.css, front/css/system-dark-patch.css
Replaces hardcoded light-gray text colors with var(--color-lightgray) across the affected selectors and adds the #txtRecord:hover rule in both dark-theme stylesheets.
Spinner-target skeleton templates
front/php/templates/skel_*.php, front/php/templates/skel_tab_tools.php
Adds spinnerTarget to the skeleton container markup across device and page templates, and creates the new tools skeleton template with its placeholder grid layout.
Skeleton reuse and spinner targeting
front/js/common.js, front/deviceDetails.php, front/deviceDetailsEdit.php, front/deviceDetailsEvents.php, front/deviceDetailsPresence.php, front/deviceDetailsSessions.php, front/deviceDetailsTools.php, front/pluginsCore.php
Updates spinner resolution in common.js, changes skeleton hide/show helpers to preserve DOM nodes, and wires page init flows to show and hide the relevant skeletons and spinner states.
Localized device link timestamps
front/devices.php, front/js/network-tree.js, front/js/ui_components.js
Changes the data-firstseen and data-lastseen attributes in the devices table, network tree, and device link renderer to store localized timestamp values.

Possibly related PRs

Poem

🐇 I hop through gray shades, both soft and bright,
My skeletons shimmer, then hide out of sight.
A spinner finds home where the tabs come alive,
And timestamps now localize just to arrive.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too generic and does not describe the main change in this pull request. Use a concise title that names the primary change, such as the new spinner/skeleton UI updates or timestamp localization work.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch next_release

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
front/deviceDetailsEdit.php (1)

487-523: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Hide the details skeleton on all save completion paths.

showDetailsTabSkeleton() is called at save start (Line 426), but hideDetailsTabSkeleton() only runs on the success branch (Line 491). On resp.success === false and AJAX error (Line 515), the skeleton stays visible and can block editing.

Suggested fix
 success: function(resp) {

   if (resp && resp.success) {
     showMessage(getString("Device_Saved_Success"));
-    hideDetailsTabSkeleton();
   } else {
     console.log(resp);
     errorMessage = resp?.error;
     showMessage(`${getString("Device_Saved_Unexpected")}: ${errorMessage}`, 5000, "modal_red");
   }

   // Remove navigation prompt
   window.onbeforeunload = null;
   somethingChanged = false;

   // Refresh API
   updateApi("devices,appevents");

   // Callback
   if (typeof refreshCallback === "function") {
     refreshCallback(direction);
   }

+  hideDetailsTabSkeleton();
   hideSpinner();
 },
 error: function(xhr) {
   if (xhr.status === 403) {
     showMessage(getString("Device_Save_Unauthorized"));
   } else {
     showMessage(getString("Device_Save_Failed") + " (" + xhr.status + ")");
   }
+  hideDetailsTabSkeleton();
   hideSpinner();
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@front/deviceDetailsEdit.php` around lines 487 - 523, The save flow in
deviceDetailsEdit.php leaves the details skeleton visible on failure paths
because hideDetailsTabSkeleton() is only called in the resp.success branch.
Update the success and error handlers in the save callback so
hideDetailsTabSkeleton() is invoked after any save completion, including
resp.success === false and xhr error cases, alongside the existing cleanup like
hideSpinner(), window.onbeforeunload, and refreshCallback.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@front/css/dark-patch.css`:
- Around line 17-24: Remove the duplicate --color-white declaration in the :root
block of dark-patch.css so each CSS variable is defined only once. Update the
color token list to keep a single --color-white entry alongside the other
--color-* variables, and ensure no other duplicate custom properties remain in
that block.

In `@front/devices.php`:
- Around line 924-925: Guard empty devFirstConnection and devLastConnection
values before calling localizeTimestamp in the hover-card markup builder so
blank timestamps stay empty instead of becoming the "Failed conversion" string.
Update the data-firstseen and data-lastseen attribute expressions to check the
row values from mapIndx(COL.devFirstConnection) and
mapIndx(COL.devLastConnection) first, and only format non-empty timestamps;
otherwise fall back to the existing "Unknown" behavior used by the UI.

In `@front/php/templates/skel_tab_maint_logging.php`:
- Line 1: The global .spinnerTarget usage makes spinner anchoring depend on DOM
order, so showSpinner()/hideSpinner() in common.js may target the wrong pane.
Update the spinner selection logic to scope to the active tab/container or
accept an explicit target instead of using $(".spinnerTarget").first(). Adjust
the templates around skel-tab-maint-logging and any other spinnerTarget markup
so the intended container is identifiable by active context, and keep the
spinner APIs consistent with that target resolution.

In `@front/php/templates/skel_tab_tools.php`:
- Line 1: The spinner overlay is being anchored to the first .spinnerTarget
instead of the active visible skeleton, which can target the wrong container
when multiple exist. Update showSpinner() and hideSpinner() to resolve the
currently active/visible spinner target explicitly, using the relevant
spinnerTarget element for the current view rather than .first(), and keep the
logic aligned with the existing spinner handling in those functions.

---

Outside diff comments:
In `@front/deviceDetailsEdit.php`:
- Around line 487-523: The save flow in deviceDetailsEdit.php leaves the details
skeleton visible on failure paths because hideDetailsTabSkeleton() is only
called in the resp.success branch. Update the success and error handlers in the
save callback so hideDetailsTabSkeleton() is invoked after any save completion,
including resp.success === false and xhr error cases, alongside the existing
cleanup like hideSpinner(), window.onbeforeunload, and refreshCallback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c14f703f-2fec-4f4a-85a7-ef9607730ba3

📥 Commits

Reviewing files that changed from the base of the PR and between cd69087 and 3f4d684.

📒 Files selected for processing (35)
  • front/css/app.css
  • front/css/dark-patch.css
  • front/css/system-dark-patch.css
  • front/deviceDetails.php
  • front/deviceDetailsEdit.php
  • front/deviceDetailsEvents.php
  • front/deviceDetailsPresence.php
  • front/deviceDetailsSessions.php
  • front/deviceDetailsTools.php
  • front/devices.php
  • front/js/network-tree.js
  • front/js/ui_components.js
  • front/php/templates/skel_devices.php
  • front/php/templates/skel_events.php
  • front/php/templates/skel_notifications.php
  • front/php/templates/skel_plugins.php
  • front/php/templates/skel_presence.php
  • front/php/templates/skel_report.php
  • front/php/templates/skel_settings.php
  • front/php/templates/skel_tab_details.php
  • front/php/templates/skel_tab_events.php
  • front/php/templates/skel_tab_maint_backup.php
  • front/php/templates/skel_tab_maint_dbtools.php
  • front/php/templates/skel_tab_maint_logging.php
  • front/php/templates/skel_tab_maint_multiedit.php
  • front/php/templates/skel_tab_plugins_table.php
  • front/php/templates/skel_tab_presence.php
  • front/php/templates/skel_tab_sessions.php
  • front/php/templates/skel_tab_sysinfo_initcheck.php
  • front/php/templates/skel_tab_sysinfo_network.php
  • front/php/templates/skel_tab_sysinfo_server.php
  • front/php/templates/skel_tab_sysinfo_storage.php
  • front/php/templates/skel_tab_tools.php
  • front/php/templates/skel_workflows.php
  • front/pluginsCore.php

Comment thread front/css/dark-patch.css Outdated
Comment thread front/devices.php
Comment on lines +924 to +925
` data-firstseen="${localizeTimestamp(row[mapIndx(COL.devFirstConnection)])}"` +
` data-lastseen="${localizeTimestamp(row[mapIndx(COL.devLastConnection)])}"` +

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Guard empty timestamps before formatting.

At Line 924 and Line 925, empty values now become "Failed conversion" (truthy), so hover cards show that literal string instead of "Unknown".

💡 Proposed fix
+            const firstSeenRaw = row[mapIndx(COL.devFirstConnection)];
+            const lastSeenRaw  = row[mapIndx(COL.devLastConnection)];
             return (
               `<b class="anonymizeDev ">` +
                 `<a href="deviceDetails.php?mac=${row[mapIndx(COL.devMac)]}" class="hover-node-info"` +
@@
-                  ` data-firstseen="${localizeTimestamp(row[mapIndx(COL.devFirstConnection)])}"` +
-                  ` data-lastseen="${localizeTimestamp(row[mapIndx(COL.devLastConnection)])}"` +
+                  ` data-firstseen="${firstSeenRaw ? localizeTimestamp(firstSeenRaw) : ''}"` +
+                  ` data-lastseen="${lastSeenRaw ? localizeTimestamp(lastSeenRaw) : ''}"` +
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
` data-firstseen="${localizeTimestamp(row[mapIndx(COL.devFirstConnection)])}"` +
` data-lastseen="${localizeTimestamp(row[mapIndx(COL.devLastConnection)])}"` +
const firstSeenRaw = row[mapIndx(COL.devFirstConnection)];
const lastSeenRaw = row[mapIndx(COL.devLastConnection)];
return (
`<b class="anonymizeDev ">` +
`<a href="deviceDetails.php?mac=${row[mapIndx(COL.devMac)]}" class="hover-node-info"` +
@@
` data-firstseen="${firstSeenRaw ? localizeTimestamp(firstSeenRaw) : ''}"` +
` data-lastseen="${lastSeenRaw ? localizeTimestamp(lastSeenRaw) : ''}"` +
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@front/devices.php` around lines 924 - 925, Guard empty devFirstConnection and
devLastConnection values before calling localizeTimestamp in the hover-card
markup builder so blank timestamps stay empty instead of becoming the "Failed
conversion" string. Update the data-firstseen and data-lastseen attribute
expressions to check the row values from mapIndx(COL.devFirstConnection) and
mapIndx(COL.devLastConnection) first, and only format non-empty timestamps;
otherwise fall back to the existing "Unknown" behavior used by the UI.

Comment thread front/php/templates/skel_tab_maint_logging.php
Comment thread front/php/templates/skel_tab_tools.php

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@front/js/common.js`:
- Around line 972-975: The resolveSpinnerTarget function currently returns the
explicitTarget result immediately, so when it matches nothing it skips the
fallback lookup and can place the spinner full-screen. Update
resolveSpinnerTarget to validate the explicitTarget selection before returning,
and if the jQuery result is empty continue on to the existing active/visible
.spinnerTarget fallback logic instead of exiting early.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 54f51c01-8b47-457b-8b33-732454109eda

📥 Commits

Reviewing files that changed from the base of the PR and between 3f4d684 and 86cc8a3.

📒 Files selected for processing (2)
  • front/css/dark-patch.css
  • front/js/common.js
💤 Files with no reviewable changes (1)
  • front/css/dark-patch.css

Comment thread front/js/common.js
Comment on lines +972 to +975
function resolveSpinnerTarget(explicitTarget = null) {
if (explicitTarget) {
return $(explicitTarget);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Invalid explicit target currently bypasses fallback target resolution.

When explicitTarget is provided but matches nothing, the function returns early and never tries active/visible .spinnerTarget fallbacks, causing unintended full-screen spinner placement.

Suggested fix
 function resolveSpinnerTarget(explicitTarget = null) {
   if (explicitTarget) {
-    return $(explicitTarget);
+    const explicit = $(explicitTarget);
+    if (explicit.length) {
+      return explicit;
+    }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function resolveSpinnerTarget(explicitTarget = null) {
if (explicitTarget) {
return $(explicitTarget);
}
function resolveSpinnerTarget(explicitTarget = null) {
if (explicitTarget) {
const explicit = $(explicitTarget);
if (explicit.length) {
return explicit;
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@front/js/common.js` around lines 972 - 975, The resolveSpinnerTarget function
currently returns the explicitTarget result immediately, so when it matches
nothing it skips the fallback lookup and can place the spinner full-screen.
Update resolveSpinnerTarget to validate the explicitTarget selection before
returning, and if the jQuery result is empty continue on to the existing
active/visible .spinnerTarget fallback logic instead of exiting early.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant