Bug 1374298 - Revisit the ping selection in about:telemetry r?chutten
Use a select with 3 optgroup (Today, Yesterday, Older) to sort ping.
MozReview-Commit-ID: 4Imw0cI3zxk
--- a/toolkit/content/aboutTelemetry.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -178,16 +178,25 @@ function padToTwoDigits(n) {
*/
function yesterday(date) {
let d = new Date(date);
d.setDate(d.getDate() - 1);
return d;
}
/**
+ * Return tomorrow's date with the same time.
+ */
+function tomorrow(date) {
+ let d = new Date(date);
+ d.setDate(d.getDate() + 1);
+ return d;
+}
+
+/**
* This returns a short date string of the form YYYY/MM/DD.
*/
function shortDateString(date) {
return date.getFullYear()
+ "/" + padToTwoDigits(date.getMonth() + 1)
+ "/" + padToTwoDigits(date.getDate());
}
@@ -292,20 +301,16 @@ var PingPicker = {
for (let el of displays) {
el.addEventListener("change", () => this.onPingDisplayChanged());
}
document.getElementById("show-subsession-data").addEventListener("change", () => {
this._updateCurrentPingData();
});
- document.getElementById("choose-ping-week").addEventListener("change", () => {
- this._renderPingList();
- this._updateArchivedPingData();
- });
document.getElementById("choose-ping-id").addEventListener("change", () => {
this._updateArchivedPingData();
});
document.getElementById("choose-ping-type").addEventListener("change", () => {
this.filterDisplayedPings();
});
@@ -349,16 +354,17 @@ var PingPicker = {
let pings = bundle.GetStringFromName("pingExplanationLink");
let pingLink = "<a href=\"http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/concepts/pings.html\">"" + pings + ""</a>";
let pingName = this._getSelectedPingName();
let pingDate = document.getElementById("ping-date");
pingDate.textContent = pingName;
pingDate.setAttribute("title", pingName);
+ // Display the type and controls if the ping is not current
let pingType = document.getElementById("ping-type");
let older = document.getElementById("older-ping");
let newer = document.getElementById("newer-ping");
if (pingName !== "current") {
pingType.hidden = false;
older.hidden = false;
newer.hidden = false;
pingType.textContent = this._getSelectedPingType();
@@ -415,180 +421,158 @@ var PingPicker = {
if (!ping) {
return;
}
displayPingData(ping, true);
},
_updateArchivedPingData() {
let id = this._getSelectedPingId();
- return TelemetryArchive.promiseArchivedPingById(id)
- .then((ping) => displayPingData(ping, true));
+ let res = Promise.resolve();
+ if (id) {
+ res = TelemetryArchive.promiseArchivedPingById(id)
+ .then((ping) => displayPingData(ping, true));
+ }
+ return res;
},
async _updateArchivedPingList(pingList) {
// The archived ping list is sorted in ascending timestamp order,
// but descending is more practical for the operations we do here.
pingList.reverse();
-
this._archivedPings = pingList;
-
- // Collect the start dates for all the weeks we have pings for.
- let weekStart = (date) => {
- let weekDay = (date.getDay() + 6) % 7;
- let monday = new Date(date);
- monday.setDate(date.getDate() - weekDay);
- return TelemetryUtils.truncateToDays(monday);
- };
-
- let weekStartDates = new Set();
- for (let p of pingList) {
- weekStartDates.add(weekStart(new Date(p.timestampCreated)).getTime());
- }
-
- // Build a list of the week date ranges we have ping data for.
- let plusOneWeek = (date) => {
- let d = date;
- d.setDate(d.getDate() + 7);
- return d;
- };
-
- this._weeks = Array.from(weekStartDates.values(), startTime => ({
- startDate: new Date(startTime),
- endDate: plusOneWeek(new Date(startTime)),
- }));
-
// Render the archive data.
- this._renderWeeks();
this._renderPingList();
-
// Update the displayed ping.
await this._updateArchivedPingData();
},
- _renderWeeks() {
- let weekSelector = document.getElementById("choose-ping-week");
- removeAllChildNodes(weekSelector);
-
- for (let week of this._weeks) {
- let text = shortDateString(week.startDate)
- + " - " + shortDateString(yesterday(week.endDate));
-
- let option = document.createElement("option");
- let content = document.createTextNode(text);
- option.appendChild(content);
- weekSelector.appendChild(option);
- }
- },
-
- _getSelectedWeek() {
- let weekSelector = document.getElementById("choose-ping-week");
- return this._weeks[weekSelector.selectedIndex];
- },
-
- _renderPingList(id = null) {
+ _renderPingList() {
let pingSelector = document.getElementById("choose-ping-id");
- removeAllChildNodes(pingSelector);
-
- let weekRange = this._getSelectedWeek();
- let pings = this._archivedPings.filter(
- (p) => p.timestampCreated >= weekRange.startDate.getTime() &&
- p.timestampCreated < weekRange.endDate.getTime());
+ Array.from(pingSelector.children).forEach((child) => removeAllChildNodes(child));
let pingTypes = new Set();
pingTypes.add(this.TYPE_ALL);
- for (let p of pings) {
+ let todayString = (new Date()).toDateString();
+ let yesterdayString = yesterday(new Date()).toDateString();
+ for (let p of this._archivedPings) {
pingTypes.add(p.type);
let date = new Date(p.timestampCreated);
- let text = shortDateString(date)
- + " " + shortTimeString(date);
+ let datetext = date.toLocaleDateString() + " " + shortTimeString(date);
+ let text = datetext + ", " + p.type;
let option = document.createElement("option");
let content = document.createTextNode(text);
option.appendChild(content);
option.setAttribute("value", p.id);
option.dataset.type = p.type;
- if (id && p.id == id) {
- option.selected = true;
+ option.dataset.date = datetext;
+
+ if (date.toDateString() == todayString) {
+ pingSelector.children[0].appendChild(option);
+ } else if (date.toDateString() == yesterdayString) {
+ pingSelector.children[1].appendChild(option);
+ } else {
+ pingSelector.children[2].appendChild(option);
}
- pingSelector.appendChild(option);
}
this._renderPingTypes(pingTypes);
},
- filterDisplayedPings() {
- let pingSelector = document.getElementById("choose-ping-id");
- let typeSelector = document.getElementById("choose-ping-type");
- let type = typeSelector.selectedOptions.item(0).value;
- if (type == this.TYPE_ALL) {
- Array.from(pingSelector.children).forEach((option) => option.hidden = false);
- pingSelector.children[0].selected = true;
- } else {
- let first = true;
- Array.from(pingSelector.children).forEach((option) => {
- if (first && option.dataset.type == type) {
- option.selected = true;
- first = false;
- }
- option.hidden = option.dataset.type != type;
- });
- }
- this._updateArchivedPingData();
- },
-
_renderPingTypes(pingTypes) {
let pingTypeSelector = document.getElementById("choose-ping-type");
removeAllChildNodes(pingTypeSelector);
pingTypes.forEach((type) => {
let option = document.createElement("option");
option.appendChild(document.createTextNode(type));
option.setAttribute("value", type);
pingTypeSelector.appendChild(option);
});
},
+ _movePingIndex(offset) {
+ if (this.viewCurrentPingData) {
+ return;
+ }
+ let typeSelector = document.getElementById("choose-ping-type");
+ let type = typeSelector.selectedOptions.item(0).value;
+
+ let id = this._getSelectedPingId();
+ let index = this._archivedPings.findIndex((p) => p.id == id);
+ let newIndex = Math.min(Math.max(0, index + offset), this._archivedPings.length - 1);
+
+ let pingList;
+ if (offset > 0) {
+ pingList = this._archivedPings.slice(newIndex);
+ } else {
+ pingList = this._archivedPings.slice(0, newIndex);
+ pingList.reverse();
+ }
+
+ let ping = pingList.find((p) => {
+ return type == this.TYPE_ALL || p.type == type;
+ });
+
+ if (ping) {
+ this.selectPing(ping);
+ this._updateArchivedPingData();
+ }
+ },
+
+ selectPing(ping) {
+ let pingSelector = document.getElementById("choose-ping-id");
+ // Use some() to break if we find the ping.
+ Array.from(pingSelector.children).some((group) => {
+ return Array.from(group.children).some((option) => {
+ if (option.value == ping.id) {
+ option.selected = true;
+ return true;
+ }
+ return false;
+ });
+ });
+ },
+
+ filterDisplayedPings() {
+ let pingSelector = document.getElementById("choose-ping-id");
+ let typeSelector = document.getElementById("choose-ping-type");
+ let type = typeSelector.selectedOptions.item(0).value;
+ let first = true;
+ Array.from(pingSelector.children).forEach((group) => {
+ Array.from(group.children).forEach((option) => {
+ if (first && option.dataset.type == type) {
+ option.selected = true;
+ first = false;
+ }
+ option.hidden = (type != this.TYPE_ALL) && (option.dataset.type != type);
+ });
+ });
+ this._updateArchivedPingData();
+ },
+
_getSelectedPingName() {
if (this.viewCurrentPingData) return "current";
let pingSelector = document.getElementById("choose-ping-id");
let selected = pingSelector.selectedOptions.item(0);
- return selected.textContent;
+ return selected.dataset.date;
},
_getSelectedPingType() {
let pingSelector = document.getElementById("choose-ping-id");
let selected = pingSelector.selectedOptions.item(0);
return selected.dataset.type;
},
_getSelectedPingId() {
let pingSelector = document.getElementById("choose-ping-id");
let selected = pingSelector.selectedOptions.item(0);
return selected.getAttribute("value");
},
- _movePingIndex(offset) {
- if (this.viewCurrentPingData) {
- return;
- }
- const id = this._getSelectedPingId();
- const index = this._archivedPings.findIndex((p) => p.id == id);
- const newIndex = Math.min(Math.max(index + offset, 0), this._archivedPings.length - 1);
- const ping = this._archivedPings[newIndex];
-
- const weekIndex = this._weeks.findIndex(
- (week) => ping.timestampCreated >= week.startDate.getTime() &&
- ping.timestampCreated < week.endDate.getTime());
- const options = document.getElementById("choose-ping-week").options;
- options.item(weekIndex).selected = true;
-
- this._renderPingList(ping.id);
- this._updateArchivedPingData();
- },
-
_showRawPingData() {
show(document.getElementById("category-raw"));
},
_showStructuredPingData() {
show(document.getElementById("category-home"));
},
};
--- a/toolkit/content/aboutTelemetry.xhtml
+++ b/toolkit/content/aboutTelemetry.xhtml
@@ -102,29 +102,30 @@
<input type="radio" id="ping-source-archive" name="choose-ping-source" value="archive" />
&aboutTelemetry.showArchivedPingData;
</div>
<div id="current-ping-picker">
<input id="show-subsession-data" type="checkbox" checked="checked" />&aboutTelemetry.showSubsessionData;
</div>
<div id="archived-ping-picker" class="hidden">
<h4 class="title">&aboutTelemetry.choosePing;</h4>
- <button class="older-ping" type="button">&aboutTelemetry.showOlderPing;</button>
- <button class="newer-ping" type="button">&aboutTelemetry.showNewerPing;</button>
- <div>
- <h4 class="title">&aboutTelemetry.archiveWeekHeader;</h4>
- <select id="choose-ping-week"></select>
- </div>
<div>
<h4 class="title">&aboutTelemetry.archivePingType;</h4>
<select id="choose-ping-type"></select>
</div>
<div>
<h4 class="title">&aboutTelemetry.archivePingHeader;</h4>
- <select id="choose-ping-id"></select>
+ <select id="choose-ping-id">
+ <optgroup label="&aboutTelemetry.optionGroupToday;">
+ </optgroup>
+ <optgroup label="&aboutTelemetry.optionGroupYesterday;">
+ </optgroup>
+ <optgroup label="&aboutTelemetry.optionGroupOlder;">
+ </optgroup>
+ </select>
</div>
</div>
<div>
<h4 class="title">&aboutTelemetry.payloadChoiceHeader;</h4>
<select id="choose-payload"></select>
</div>
</div>
--- a/toolkit/locales/en-US/chrome/global/aboutTelemetry.dtd
+++ b/toolkit/locales/en-US/chrome/global/aboutTelemetry.dtd
@@ -43,16 +43,28 @@ Week
<!ENTITY aboutTelemetry.archivePingType "
Ping Type
">
<!ENTITY aboutTelemetry.archivePingHeader "
Ping
">
+<!ENTITY aboutTelemetry.optionGroupToday "
+Today
+">
+
+<!ENTITY aboutTelemetry.optionGroupYesterday "
+Yesterday
+">
+
+<!ENTITY aboutTelemetry.optionGroupOlder "
+Older
+">
+
<!ENTITY aboutTelemetry.generalDataSection "
General Data
">
<!ENTITY aboutTelemetry.environmentDataSection "
Environment Data
">