Commit ab3e1965 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Media History] Add tabs to Web UI

Add tabs to the WebUI because we want a tab
for each table. For now this is stats and origins
but we will soon add two more.

BUG=1024353

Change-Id: I0af5b286d3234dc1d87b4218de8d8455140e648e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2040178
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#740076}
parent 4c12a790
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
<title>Media History</title> <title>Media History</title>
<meta charset="utf-8"> <meta charset="utf-8">
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<link rel="stylesheet" href="chrome://resources/css/tabs.css">
<script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script> <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
<script src="chrome://resources/js/promise_resolver.js"></script> <script src="chrome://resources/js/promise_resolver.js"></script>
<script src="chrome://resources/js/util.js"></script> <script src="chrome://resources/js/util.js"></script>
...@@ -11,14 +13,43 @@ ...@@ -11,14 +13,43 @@
<script src="chrome://resources/mojo/mojo/public/mojom/base/time.mojom-lite.js"></script> <script src="chrome://resources/mojo/mojo/public/mojom/base/time.mojom-lite.js"></script>
<script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script> <script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
<script src="chrome://resources/mojo/url/mojom/origin.mojom-lite.js"></script> <script src="chrome://resources/mojo/url/mojom/origin.mojom-lite.js"></script>
<script src="chrome/browser/media/history/media_history_store.mojom-lite.js"> <script src="chrome/browser/media/history/media_history_store.mojom-lite.js"></script>
</script>
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/cr/ui.js"></script>
<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
<script src="chrome://resources/js/cr/ui/tabs.js"></script>
<script src="chrome://media-history/media-history.js"></script> <script src="chrome://media-history/media-history.js"></script>
<style> <style>
html,
body { body {
font-family: 'Roboto', 'Noto', sans-serif; font-family: 'Roboto', 'Noto', sans-serif;
font-size: 14px; font-size: 14px;
height: 100%;
margin: 0;
padding: 0;
width: 100%;
}
tabbox {
padding-top: 10px;
}
tab {
-webkit-user-select: none;
}
body tabpanels {
box-shadow: none;
}
tabpanel {
padding: 10px;
}
h1 {
margin-top: 10px;
} }
button { button {
...@@ -66,42 +97,56 @@ ...@@ -66,42 +97,56 @@
</style> </style>
</head> </head>
<body> <body>
<h1>Media History</h1> <tabbox id="tabbox">
<button id="copy-all-to-clipboard">Copy all to clipboard</button> <tabs>
<table> <tab id="stats">Stats</tab>
<thead> <tab id="origins">Origins</tab>
<tr id="stats-table-header"> </tabs>
<th> <tabpanels>
Table Name <tabpanel>
</th> <h1>Media History</h1>
<th> <button class="copy-all-to-clipboard">Copy all to clipboard</button>
Row Count <table>
</th> <thead>
</tr> <tr id="stats-table-header">
</thead> <th>
<tbody id="stats-table-body"> Table Name
</tbody> </th>
</table> <th>
<table> Row Count
<thead> </th>
<tr id="data-table-header"> </tr>
<th sort-key="origin"> </thead>
Origin <tbody id="stats-table-body">
</th> </tbody>
<th sort-key="lastUpdatedTime" sort-reverse> </table>
Last Updated </tabpanel>
</th> <tabpanel>
<th sort-key="cachedAudioVideoWatchtime" class="sort-column" sort-reverse> <h1>Origins</h1>
Audio + Video Watchtime (secs, cached) <button class="copy-all-to-clipboard">Copy all to clipboard</button>
</th> <table>
<th sort-key="actualAudioVideoWatchtime" sort-reverse> <thead>
Audio + Video Watchtime (secs, actual) <tr id="data-table-header">
</th> <th sort-key="origin">
</tr> Origin
</thead> </th>
<tbody id="data-table-body"> <th sort-key="lastUpdatedTime" sort-reverse>
</tbody> Last Updated
</table> </th>
<th sort-key="cachedAudioVideoWatchtime" class="sort-column" sort-reverse>
Audio + Video Watchtime (secs, cached)
</th>
<th sort-key="actualAudioVideoWatchtime" sort-reverse>
Audio + Video Watchtime (secs, actual)
</th>
</tr>
</thead>
<tbody id="data-table-body">
</tbody>
</table>
</tabpanel>
</tabpanels>
</tabbox>
<template id="data-row"> <template id="data-row">
<tr> <tr>
......
...@@ -5,21 +5,12 @@ ...@@ -5,21 +5,12 @@
'use strict'; 'use strict';
// Allow a function to be provided by tests, which will be called when // Allow a function to be provided by tests, which will be called when
// the page has been populated with media history details. // the page has been populated.
const pageIsPopulatedResolver = new PromiseResolver(); const pageIsPopulatedResolver = new PromiseResolver();
let pageIsPopulatedCounter = 0;
function whenPageIsPopulatedForTest() { function whenPageIsPopulatedForTest() {
return pageIsPopulatedResolver.promise; return pageIsPopulatedResolver.promise;
} }
function maybeResolvePageIsPopulated() {
pageIsPopulatedCounter--;
if (pageIsPopulatedCounter == 0) {
pageIsPopulatedResolver.resolve();
}
}
(function() { (function() {
let data = null; let data = null;
...@@ -146,23 +137,24 @@ function renderStatsTable(stats) { ...@@ -146,23 +137,24 @@ function renderStatsTable(stats) {
} }
/** /**
* Retrieve stats from the backend and then render the table. * @param {!string} name The name of the tab to show.
* @return {Promise}
*/ */
function updateTable() { function showTab(name) {
pageIsPopulatedCounter += 2; switch (name) {
case 'stats':
// Populate stats table. return store.getMediaHistoryStats().then(response => {
store.getMediaHistoryStats().then(response => { renderStatsTable(response.stats);
renderStatsTable(response.stats); });
maybeResolvePageIsPopulated(); case 'origins':
}); return store.getMediaHistoryOriginRows().then(response => {
data = response.rows;
renderDataTable();
});
}
// Populate origin table. // Return an empty promise if there is no tab.
store.getMediaHistoryOriginRows().then(response => { return new Promise();
data = response.rows;
renderDataTable();
maybeResolvePageIsPopulated();
});
} }
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
...@@ -170,7 +162,30 @@ document.addEventListener('DOMContentLoaded', function() { ...@@ -170,7 +162,30 @@ document.addEventListener('DOMContentLoaded', function() {
dataTableBody = $('data-table-body'); dataTableBody = $('data-table-body');
statsTableBody = $('stats-table-body'); statsTableBody = $('stats-table-body');
updateTable();
cr.ui.decorate('tabbox', cr.ui.TabBox);
// Allow tabs to be navigated to by fragment. The fragment with be of the
// format "#tab-<tab id>".
window.onhashchange = function() {
showTab(window.location.hash.substr(5));
};
// Default to the stats tab.
if (!window.location.hash.substr(5)) {
window.location.hash = 'tab-stats';
} else {
showTab(window.location.hash.substr(5))
.then(pageIsPopulatedResolver.resolve);
}
// When the tab updates, update the anchor.
$('tabbox').addEventListener('selectedChange', function() {
const tabbox = $('tabbox');
const tabs = tabbox.querySelector('tabs').children;
const selectedTab = tabs[tabbox.selectedIndex];
window.location.hash = 'tab-' + selectedTab.id;
}, true);
// Set table header sort handlers. // Set table header sort handlers.
const dataTableHeader = $('data-table-header'); const dataTableHeader = $('data-table-header');
...@@ -196,17 +211,21 @@ document.addEventListener('DOMContentLoaded', function() { ...@@ -196,17 +211,21 @@ document.addEventListener('DOMContentLoaded', function() {
}); });
} }
// Add handler to 'copy all to clipboard' button // Add handler to 'copy all to clipboard' button.
const copyAllToClipboardButton = $('copy-all-to-clipboard'); const copyAllToClipboardButtons =
copyAllToClipboardButton.addEventListener('click', (e) => { document.querySelectorAll('.copy-all-to-clipboard');
// Make sure nothing is selected
window.getSelection().removeAllRanges(); copyAllToClipboardButtons.forEach((button) => {
button.addEventListener('click', (e) => {
// Make sure nothing is selected.
window.getSelection().removeAllRanges();
document.execCommand('selectAll'); document.execCommand('selectAll');
document.execCommand('copy'); document.execCommand('copy');
// And deselect everything at the end. // And deselect everything at the end.
window.getSelection().removeAllRanges(); window.getSelection().removeAllRanges();
});
}); });
}); });
})(); })();
...@@ -15,8 +15,6 @@ function MediaHistoryWebUIBrowserTest() {} ...@@ -15,8 +15,6 @@ function MediaHistoryWebUIBrowserTest() {}
MediaHistoryWebUIBrowserTest.prototype = { MediaHistoryWebUIBrowserTest.prototype = {
__proto__: testing.Test.prototype, __proto__: testing.Test.prototype,
browsePreload: 'chrome://media-history',
featureList: {enabled: ['media::kUseMediaHistoryStore']}, featureList: {enabled: ['media::kUseMediaHistoryStore']},
isAsync: true, isAsync: true,
...@@ -34,7 +32,20 @@ GEN('#else'); ...@@ -34,7 +32,20 @@ GEN('#else');
GEN('#define MAYBE_All All'); GEN('#define MAYBE_All All');
GEN('#endif'); GEN('#endif');
TEST_F('MediaHistoryWebUIBrowserTest', 'MAYBE_All', function() { /**
* Tests for the stats tab.
* @extends {MediaHistoryWebUIBrowserTest}
*/
function MediaHistoryStatsWebUIBrowserTest() {}
MediaHistoryStatsWebUIBrowserTest.prototype = {
__proto__: MediaHistoryWebUIBrowserTest.prototype,
/** @override */
browsePreload: 'chrome://media-history#tab-stats',
};
TEST_F('MediaHistoryStatsWebUIBrowserTest', 'MAYBE_All', function() {
suiteSetup(function() { suiteSetup(function() {
return whenPageIsPopulatedForTest(); return whenPageIsPopulatedForTest();
}); });
...@@ -52,6 +63,27 @@ TEST_F('MediaHistoryWebUIBrowserTest', 'MAYBE_All', function() { ...@@ -52,6 +63,27 @@ TEST_F('MediaHistoryWebUIBrowserTest', 'MAYBE_All', function() {
x => [x.children[0].textContent, x.children[1].textContent])); x => [x.children[0].textContent, x.children[1].textContent]));
}); });
mocha.run();
});
/**
* Tests for the origins tab.
* @extends {MediaHistoryWebUIBrowserTest}
*/
function MediaHistoryOriginsWebUIBrowserTest() {}
MediaHistoryOriginsWebUIBrowserTest.prototype = {
__proto__: MediaHistoryWebUIBrowserTest.prototype,
/** @override */
browsePreload: 'chrome://media-history#tab-origins',
};
TEST_F('MediaHistoryOriginsWebUIBrowserTest', 'MAYBE_All', function() {
suiteSetup(function() {
return whenPageIsPopulatedForTest();
});
test('check data table is loaded', () => { test('check data table is loaded', () => {
let dataHeaderRows = let dataHeaderRows =
Array.from(document.getElementById('data-table-header').children); Array.from(document.getElementById('data-table-header').children);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment