diff --git a/.last-branch b/.last-branch
index d5e3c52..8c90e92 100644
--- a/.last-branch
+++ b/.last-branch
@@ -1 +1 @@
-v20260109-01-veeam-m365-overall-message
+v20260109-02-object-list-sorting
diff --git a/containers/backupchecks/src/templates/main/admin_all_mail.html b/containers/backupchecks/src/templates/main/admin_all_mail.html
index 9fd5c33..5c76e0b 100644
--- a/containers/backupchecks/src/templates/main/admin_all_mail.html
+++ b/containers/backupchecks/src/templates/main/admin_all_mail.html
@@ -235,6 +235,33 @@
if (el) el.textContent = value || '';
}
+ function objectSeverityRank(o) {
+ var st = String((o && o.status) || '').trim().toLowerCase();
+ var err = String((o && o.error_message) || '').trim();
+ if (st === 'error' || st === 'failed' || st === 'failure' || err) return 0;
+ if (st === 'warning') return 1;
+ return 2;
+ }
+
+ function sortObjects(objects) {
+ return (objects || []).slice().sort(function (a, b) {
+ var ra = objectSeverityRank(a);
+ var rb = objectSeverityRank(b);
+ if (ra !== rb) return ra - rb;
+
+ var na = String((a && a.name) || '').toLowerCase();
+ var nb = String((b && b.name) || '').toLowerCase();
+ if (na < nb) return -1;
+ if (na > nb) return 1;
+
+ var ta = String((a && a.type) || '').toLowerCase();
+ var tb = String((b && b.type) || '').toLowerCase();
+ if (ta < tb) return -1;
+ if (ta > tb) return 1;
+ return 0;
+ });
+ }
+
function renderObjects(objects) {
var container = document.getElementById('msg_objects_container');
if (!container) return;
@@ -248,8 +275,10 @@
var tableHtml = '
' +
'| Name | Type | Status | Error |
';
- for (var i = 0; i < objects.length; i++) {
- var o = objects[i] || {};
+ var sorted = sortObjects(objects);
+
+ for (var i = 0; i < sorted.length; i++) {
+ var o = sorted[i] || {};
tableHtml += '' +
'| ' + (o.name || '') + ' | ' +
'' + (o.type || '') + ' | ' +
diff --git a/containers/backupchecks/src/templates/main/daily_jobs.html b/containers/backupchecks/src/templates/main/daily_jobs.html
index 4fc11a1..bc6783d 100644
--- a/containers/backupchecks/src/templates/main/daily_jobs.html
+++ b/containers/backupchecks/src/templates/main/daily_jobs.html
@@ -293,6 +293,33 @@
return "";
}
+ function objectSeverityRank(o) {
+ var st = String((o && o.status) || '').trim().toLowerCase();
+ var err = String((o && o.error_message) || '').trim();
+ if (st === 'error' || st === 'failed' || st === 'failure' || err) return 0;
+ if (st === 'warning') return 1;
+ return 2;
+ }
+
+ function sortObjects(objects) {
+ return (objects || []).slice().sort(function (a, b) {
+ var ra = objectSeverityRank(a);
+ var rb = objectSeverityRank(b);
+ if (ra !== rb) return ra - rb;
+
+ var na = String((a && a.name) || '').toLowerCase();
+ var nb = String((b && b.name) || '').toLowerCase();
+ if (na < nb) return -1;
+ if (na > nb) return 1;
+
+ var ta = String((a && a.type) || '').toLowerCase();
+ var tb = String((b && b.type) || '').toLowerCase();
+ if (ta < tb) return -1;
+ if (ta > tb) return 1;
+ return 0;
+ });
+ }
+
function wrapMailHtml(html) {
@@ -606,7 +633,7 @@ if (tStatus) tStatus.textContent = '';
var tbody = document.querySelector("#dj_objects_table tbody");
tbody.innerHTML = "";
- (run.objects || []).forEach(function (obj) {
+ sortObjects(run.objects || []).forEach(function (obj) {
var tr = document.createElement("tr");
var tdName = document.createElement("td");
diff --git a/containers/backupchecks/src/templates/main/inbox.html b/containers/backupchecks/src/templates/main/inbox.html
index 4dc82b5..328ef18 100644
--- a/containers/backupchecks/src/templates/main/inbox.html
+++ b/containers/backupchecks/src/templates/main/inbox.html
@@ -369,10 +369,39 @@ function findCustomerIdByName(name) {
return;
}
+ function objectSeverityRank(o) {
+ var st = String((o && o.status) || "").trim().toLowerCase();
+ var err = String((o && o.error_message) || "").trim();
+ if (st === "error" || st === "failed" || st === "failure" || err) return 0;
+ if (st === "warning") return 1;
+ return 2;
+ }
+
+ function sortObjects(list) {
+ return (list || []).slice().sort(function (a, b) {
+ var ra = objectSeverityRank(a);
+ var rb = objectSeverityRank(b);
+ if (ra !== rb) return ra - rb;
+
+ var na = String((a && a.name) || "").toLowerCase();
+ var nb = String((b && b.name) || "").toLowerCase();
+ if (na < nb) return -1;
+ if (na > nb) return 1;
+
+ var ta = String((a && a.type) || "").toLowerCase();
+ var tb = String((b && b.type) || "").toLowerCase();
+ if (ta < tb) return -1;
+ if (ta > tb) return 1;
+ return 0;
+ });
+ }
+
+ var sorted = sortObjects(objects);
+
var html = "";
html += "| Object | Type | Status | Error |
";
- for (var i = 0; i < objects.length; i++) {
- var o = objects[i] || {};
+ for (var i = 0; i < sorted.length; i++) {
+ var o = sorted[i] || {};
html += "";
html += "| " + (o.name || "") + " | ";
html += "" + (o.type || "") + " | ";
diff --git a/containers/backupchecks/src/templates/main/job_detail.html b/containers/backupchecks/src/templates/main/job_detail.html
index 11913af..8495532 100644
--- a/containers/backupchecks/src/templates/main/job_detail.html
+++ b/containers/backupchecks/src/templates/main/job_detail.html
@@ -497,18 +497,29 @@
return;
}
- // Sort: objects with an error_message first (alphabetically by name), then the rest (also by name).
- var sorted = (objects || []).slice().sort(function (a, b) {
- a = a || {};
- b = b || {};
- var aHasErr = !!(a.error_message && a.error_message.toString().trim());
- var bHasErr = !!(b.error_message && b.error_message.toString().trim());
- if (aHasErr !== bHasErr) return aHasErr ? -1 : 1;
+ function objectSeverityRank(o) {
+ var st = String((o && o.status) || "").trim().toLowerCase();
+ var err = String((o && o.error_message) || "").trim();
+ if (st === "error" || st === "failed" || st === "failure" || err) return 0;
+ if (st === "warning") return 1;
+ return 2;
+ }
- var an = (a.name || "").toString().toLowerCase();
- var bn = (b.name || "").toString().toLowerCase();
+ // Sort: errors first, then warnings, then the rest; within each group sort alphabetically.
+ var sorted = (objects || []).slice().sort(function (a, b) {
+ var ra = objectSeverityRank(a);
+ var rb = objectSeverityRank(b);
+ if (ra !== rb) return ra - rb;
+
+ var an = String((a && a.name) || "").toLowerCase();
+ var bn = String((b && b.name) || "").toLowerCase();
if (an < bn) return -1;
if (an > bn) return 1;
+
+ var at = String((a && a.type) || "").toLowerCase();
+ var bt = String((b && b.type) || "").toLowerCase();
+ if (at < bt) return -1;
+ if (at > bt) return 1;
return 0;
});
diff --git a/containers/backupchecks/src/templates/main/run_checks.html b/containers/backupchecks/src/templates/main/run_checks.html
index 597f464..72981ef 100644
--- a/containers/backupchecks/src/templates/main/run_checks.html
+++ b/containers/backupchecks/src/templates/main/run_checks.html
@@ -324,6 +324,33 @@ function statusClass(status) {
return "";
}
+ function objectSeverityRank(o) {
+ var st = String((o && o.status) || '').trim().toLowerCase();
+ var err = String((o && o.error_message) || '').trim();
+ if (st === 'error' || st === 'failed' || st === 'failure' || err) return 0;
+ if (st === 'warning') return 1;
+ return 2;
+ }
+
+ function sortObjects(objects) {
+ return (objects || []).slice().sort(function (a, b) {
+ var ra = objectSeverityRank(a);
+ var rb = objectSeverityRank(b);
+ if (ra !== rb) return ra - rb;
+
+ var na = String((a && a.name) || '').toLowerCase();
+ var nb = String((b && b.name) || '').toLowerCase();
+ if (na < nb) return -1;
+ if (na > nb) return 1;
+
+ var ta = String((a && a.type) || '').toLowerCase();
+ var tb = String((b && b.type) || '').toLowerCase();
+ if (ta < tb) return -1;
+ if (ta > tb) return 1;
+ return 0;
+ });
+ }
+
function wrapMailHtml(html) {
html = html || "";
return (
@@ -940,7 +967,7 @@ if (tStatus) tStatus.textContent = '';
var tbody = document.querySelector('#rcm_objects_table tbody');
if (tbody) {
tbody.innerHTML = '';
- (run.objects || []).forEach(function (obj) {
+ sortObjects(run.objects || []).forEach(function (obj) {
var tr = document.createElement('tr');
var tdName = document.createElement('td');
diff --git a/docs/changelog.md b/docs/changelog.md
index b9e897a..27e37ad 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -4,6 +4,17 @@
- Improved extraction of the overall details message from the mail content, ensuring permission and role warnings are correctly captured.
- Ensured the extracted overall message is consistently available in job details, run checks, and reporting views.
+---
+
+## v20260109-02-object-list-sorting
+
+- Updated object list sorting logic to improve readability and prioritization.
+- Objects are now grouped by severity in the following order:
+ 1. Errors
+ 2. Warnings
+ 3. All other statuses
+- Within each severity group, objects are sorted alphabetically (A–Z).
+- Applied consistent sorting across all relevant views, including Inbox, Job Details, Run Checks, Daily Jobs, and Admin All Mail.
================================================================================================================================================
## v0.1.19