diff --git a/global.js b/global.js
index b130a86..d08414d 100644
--- a/global.js
+++ b/global.js
@@ -625,74 +625,63 @@ function timeString(ms, includeSuffix)
var suffix = "";
if (includeSuffix) {
if (ms < 0) {
- suffix = "from now";
+ suffix = " from now";
ms = -ms;
} else {
- suffix = "ago";
+ suffix = " ago";
}
}
- // Break into units
- var years = 0, days = 0, hours = 0, minutes = 0, seconds = 0;
- while (ms >= 31536000000) {
- ms -= 31536000000;
- years++;
+ // Break into years, days, hours, minutes, seconds, and ms
+ var units = [0, 0, 0, 0, 0, ms.toFixed(0)];
+ var unitNames = ["year", "day", "hour", "minute", "second", "millisecond"];
+ while (units[5] >= 31536000000) {
+ units[5] -= 31536000000;
+ units[0]++;
}
- while (ms >= 86400000) {
- ms -= 86400000;
- days++;
+ while (units[5] >= 86400000) {
+ units[5] -= 86400000;
+ units[1]++;
}
- while (ms >= 3600000) {
- ms -= 3600000;
- hours++;
+ while (units[5] >= 3600000) {
+ units[5] -= 3600000;
+ units[2]++;
}
- while (ms >= 60000) {
- ms -= 60000;
- minutes++;
+ while (units[5] >= 60000) {
+ units[5] -= 60000;
+ units[3]++;
}
- while (ms >= 1000) {
- ms -= 1000;
- seconds++;
+ while (units[5] >= 1000) {
+ units[5] -= 1000;
+ units[4]++;
}
- // Stringify
- if (years == 1)
- years = years + " year";
- else
- years = years + " years";
- if (days == 1)
- days = days + " day";
- else
- days = days + " days";
- if (hours == 1)
- hours = hours + " hour";
- else
- hours = hours + " hours";
- if (minutes == 1)
- minutes = minutes + " minute";
- else
- minutes = minutes + " minutes";
- if (seconds == 1)
- seconds = seconds + " second";
- else
- seconds = seconds + " seconds";
- if (ms == 1)
- ms = ms + " millisecond";
- else
- ms = ms + " milliseconds";
+ // Grab the first two non-zero units
+ var first = "";
+ var second = "";
+ for (var i = 0; i < units.length; i++) {
+ if (!units[i])
+ continue;
- // Return the final string
- if (years[0] != "0")
- return years + " " + days + " " + suffix;
- if (days[0] != "0")
- return days + " " + hours + " " + suffix;
- if (hours[0] != "0")
- return hours + " " + minutes + " " + suffix;
- if (minutes[0] != "0")
- return minutes + " " + seconds + " " + suffix;
- if (seconds[0] != "0")
- return seconds + " " + ms + " " + suffix;
- return ms + " " + suffix;
+ if (!first.length) {
+ first = units[i] + " " + unitNames[i];
+ if (units[i] > 1)
+ first += "s";
+ continue;
+ }
+
+ if (!second.length) {
+ second = " " + units[i] + " " + unitNames[i];
+ if (units[i] > 1)
+ second += "s";
+ break;
+ }
+ }
+
+ if (!first.length)
+ return "0 milliseconds" + suffix;
+ else
+ return first + second + suffix;
}
// Translates a kernel slug into a label and sets the contents of an element
diff --git a/linodes/dashboard/dashboard.js b/linodes/dashboard/dashboard.js
index bb9bb89..ebdd715 100644
--- a/linodes/dashboard/dashboard.js
+++ b/linodes/dashboard/dashboard.js
@@ -317,22 +317,37 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
var eventDate = new Date(event.created + "Z");
var curDate = new Date();
jobInfo.innerHTML = "Entered: " + timeString(curDate - eventDate, true);
- if (event.percent_complete && event.percent_complete != 100)
- jobInfo.innerHTML += " - " + event.percent_complete + "%";
- if (event.time_remaining) {
- var times = event.time_remaining.split(":");
- var ms = 0;
- ms += parseInt(times[0]) * 3600000;
- ms += parseInt(times[1]) * 60000;
- ms += parseInt(times[2]) * 1000;
- jobInfo.innerHTML += " - " + timeString(ms, false) + " Remaining";
- }
+ if (event.duration)
+ jobInfo.innerHTML += " - Took: " + timeString(event.duration * 1000, false);
+ else if (event.status != "notification")
+ jobInfo.innerHTML += " - Waiting...";
detailsCell.appendChild(jobType);
detailsCell.appendChild(jobDetails);
detailsCell.appendChild(br);
detailsCell.appendChild(jobInfo);
row.appendChild(detailsCell);
+ // Progress cell
+ var progressCell = document.createElement("td");
+ if (event.percent_complete && event.percent_complete != 100)
+ progressCell.innerHTML = event.percent_complete + "%";
+ if (event.time_remaining) {
+ if (progressCell.innerHTML.length)
+ progressCell.innerHTML += ", ";
+ var times = event.time_remaining.split(":");
+ var ms = 0;
+ ms += parseInt(times[0]) * 3600000;
+ ms += parseInt(times[1]) * 60000;
+ ms += parseInt(times[2]) * 1000;
+ progressCell.innerHTML += timeString(ms, false) + " to go";
+ }
+ if (event.rate) {
+ if (progressCell.innerHTML.length)
+ progressCell.innerHTML += ", ";
+ progressCell.innerHTML += event.rate;
+ }
+ row.appendChild(progressCell);
+
return row;
};
@@ -427,33 +442,6 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
});
};
- // Callback for backups API call
- var displayBackups = function(response)
- {
- // Find time of most recent backup
- var mostRecent = new Date(0);
- for (var i = 0; i < response.automatic.length; i++) {
- if (response.automatic[i].status == "successful") {
- var time = new Date(response.automatic[i].finished + "Z");
- if (time > mostRecent)
- mostRecent = time;
- }
- }
- if (response.snapshot.current && response.snapshot.current.status == "successful") {
- var time = new Date(response.snapshot.current.finished + "Z");
- if (time > mostRecent)
- mostRecent = time;
- }
-
- // 1970 means no backups happened
- if (mostRecent.getUTCFullYear() == 1970)
- return;
-
- var curDate = new Date();
- ui.lastBackupTime.innerHTML = timeString(curDate - mostRecent, true);
- ui.lastBackup.style.display = "block";
- };
-
// Callback for config profile API call
var displayConfigs = function(response)
{
@@ -516,6 +504,12 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
if (data.linode.backups.enabled) {
ui.backups.innerHTML = "Enabled!";
ui.backups.className += " " + elements.backupsEnabled;
+ if (data.linode.backups.last_successful) {
+ var backupDate = new Date(data.linode.backups.last_successful + "Z");
+ var now = new Date();
+ ui.lastBackupTime.innerHTML = timeString(now - backupDate, true);
+ ui.lastBackup.style.display = "block";
+ }
} else {
ui.backups.innerHTML = "";
var text = document.createElement("span");
@@ -821,7 +815,6 @@ import { settings, elements, apiDelete, apiGet, apiPost, eventTitles, parseParam
apiGet("/linode/instances/" + data.params.lid + "/disks", displayDisks, null);
apiGet("/linode/instances/" + data.params.lid + "/volumes", displayVolumes, null);
apiGet("/linode/instances/" + data.params.lid + "/transfer", displayTransfer, null);
- apiGet("/linode/instances/" + data.params.lid + "/backups", displayBackups, null);
var filter = {
"entity.type": "linode",
"entity.id": parseInt(data.params.lid)
diff --git a/linodes/dashboard/index.shtml b/linodes/dashboard/index.shtml
index c47b7be..073a3fd 100644
--- a/linodes/dashboard/index.shtml
+++ b/linodes/dashboard/index.shtml
@@ -94,16 +94,17 @@ along with Linode Manager Classic. If not, see
Host Job Queue (more) | +Host Job Queue (more) | |||
+ | ||||
Loading jobs... | +