Commit 3364e996 authored by Alex Danilo's avatar Alex Danilo Committed by Commit Bot

Enable error indicators on summary panel

Adds support for showing an error indication marker on the summary panel
when a display panel contains a mixture of progress panel items and
error panel items.

Enables a summary panel that shows an error indicator in the case where
there are multiple error panel items hosted by the display panel but
there are no progress panel items hosted.

Adds unit test to cover these cases and implements a convenience
function removeAllPanelItems() to clear out all panel items hosted in a
display panel.

Bug: 1014771
Tests: browser_tests --gtest_filter=FileManagerJsTest.FilesDisplayPanel
Change-Id: I86047d47cb666f069cbe9260504f100d4a63e733
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1888233
Commit-Queue: Alex Danilo <adanilo@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710676}
parent f44b33c7
......@@ -10,6 +10,12 @@ function setUpPage() {
'<xf-display-panel id="test-xf-display-panel"></xf-display-panel>';
}
function tearDown() {
/** @type {!DisplayPanel|!Element} */
const displayPanel = assert(document.querySelector('#test-xf-display-panel'));
displayPanel.removeAllPanelItems();
}
async function testDisplayPanelAttachPanel(done) {
// Get the host display panel container element.
/** @type {!DisplayPanel|!Element} */
......@@ -165,6 +171,52 @@ function testFilesDisplayPanelErrorMarker() {
'Summary panel error marker property is wrong, should be "hidden"');
}
function testFilesDisplayPanelMixedSummary() {
// Get the host display panel container element.
/** @type {!DisplayPanel|!Element} */
const displayPanel = assert(document.querySelector('#test-xf-display-panel'));
// Add an error panel item to the display panel container.
let errorPanel = displayPanel.addPanelItem('testpanel1');
errorPanel.panelType = errorPanel.panelTypeError;
assertEquals('status', errorPanel.indicator);
// Add a progress panel item to the display panel container.
const progressPanel = displayPanel.addPanelItem('testpanel2');
progressPanel.panelType = progressPanel.panelTypeProgress;
// Verify a summary panel item is created and shows the error indicator.
const summaryContainer = displayPanel.shadowRoot.querySelector('#summary');
let summaryPanelItem = summaryContainer.querySelector('xf-panel-item');
assertEquals(summaryPanelItem.panelTypeSummary, summaryPanelItem.panelType);
assertEquals('largeprogress', summaryPanelItem.indicator);
assertEquals('visible', summaryPanelItem.errorMarkerVisibility);
// Remove the error panel item and add a second progress panel item.
displayPanel.removePanelItem(errorPanel);
const extraProgressPanel = displayPanel.addPanelItem('testpanel3');
extraProgressPanel.panelType = extraProgressPanel.panelTypeProgress;
// Verify a summary panel item is created without an error indicator.
summaryPanelItem = summaryContainer.querySelector('xf-panel-item');
assertEquals(summaryPanelItem.panelTypeSummary, summaryPanelItem.panelType);
assertEquals('largeprogress', summaryPanelItem.indicator);
assertEquals('hidden', summaryPanelItem.errorMarkerVisibility);
// Remove the progress panel items and add 2 error panel items.
displayPanel.removePanelItem(progressPanel);
displayPanel.removePanelItem(extraProgressPanel);
errorPanel = displayPanel.addPanelItem('testpanel4');
errorPanel.panelType = errorPanel.panelTypeError;
const extraErrorPanel = displayPanel.addPanelItem('testpanel5');
extraErrorPanel.panelType = extraErrorPanel.panelTypeError;
// Verify a summary panel item is shown, with an error status indicator.
summaryPanelItem = summaryContainer.querySelector('xf-panel-item');
assertEquals(summaryPanelItem.panelTypeSummary, summaryPanelItem.panelType);
assertEquals('status', summaryPanelItem.indicator);
}
async function testFilesDisplayPanelSummaryPanel(done) {
// Get the host display panel container element.
/** @type {!DisplayPanel|!Element} */
......
......@@ -223,6 +223,15 @@ class DisplayPanel extends HTMLElement {
}
}
/**
* Get an array of panel items that are connected to the DOM.
* @return {!Array<PanelItem>}
* @private
*/
connectedPanelItems_() {
return this.items_.filter(item => item.isConnected);
}
/**
* Update the summary panel item progress indicator.
* @public
......@@ -233,20 +242,44 @@ class DisplayPanel extends HTMLElement {
if (this.items_.length == 0) {
return;
}
for (let i = 0; i < this.items_.length; ++i) {
let panel = this.items_[i];
let errors = 0, progressCount = 0;
const connectedPanels = this.connectedPanelItems_();
for (const panel of connectedPanels) {
// Only sum progress for attached progress panels.
if ((panel.panelType === panel.panelTypeProgress) &&
panel.parentNode !== null) {
if (panel.panelType === panel.panelTypeProgress) {
total += Number(panel.progress);
progressCount++;
} else if (panel.panelType === panel.panelTypeError) {
errors++;
}
}
if (progressCount > 0) {
total /= progressCount;
}
total /= this.items_.length;
const summaryPanel = this.summary_.querySelector('xf-panel-item');
if (summaryPanel) {
// Show either a progress indicator or error count if no operations going.
if (progressCount > 0) {
// Make sure we have a progress indicator on the summary panel.
if (summaryPanel.indicator != 'largeprogress') {
summaryPanel.indicator = 'largeprogress';
}
// TODO(crbug.com/947388) i18n this string (add setter).
summaryPanel.primaryText = total.toFixed(0) + '% complete';
summaryPanel.progress = total;
summaryPanel.setAttribute('count', progressCount);
summaryPanel.errorMarkerVisibility =
(errors > 0) ? 'visible' : 'hidden';
} else {
assert(errors > 0);
// Make sure we have a failure indicator on the summary panel.
if (summaryPanel.indicator != 'status') {
summaryPanel.indicator = 'status';
summaryPanel.status = 'failure';
}
// TODO(crbug.com/947388) i18n this string (add setter/callback?).
summaryPanel.primaryText = errors + ' errors';
}
}
}
......@@ -263,16 +296,9 @@ class DisplayPanel extends HTMLElement {
if (this.hasAttribute('aria-label')) {
this.tabIndex = this.items_.length ? 0 : -1;
}
// Work out how many progress panels are being shown.
let count = 0;
for (let i = 0; i < this.items_.length; ++i) {
let panel = this.items_[i];
if ((panel.panelType === panel.panelTypeProgress) &&
panel.parentNode !== null) {
count++;
}
}
// If there's only one progress panel item active, no need for summary.
// Work out how many panel items are being shown.
const count = this.connectedPanelItems_().length;
// If there's only one panel item active, no need for summary.
if (count <= 1 && summaryPanel) {
const button = summaryPanel.primaryButton;
if (button) {
......@@ -284,7 +310,7 @@ class DisplayPanel extends HTMLElement {
this.panels_.classList.remove('collapsed');
return;
}
// Show summary panel if there are more than 1 progress panels.
// Show summary panel if there are more than 1 panel items.
if (count > 1 && !summaryPanel) {
summaryPanel = document.createElement('xf-panel-item');
summaryPanel.setAttribute('panel-type', 1);
......@@ -304,7 +330,6 @@ class DisplayPanel extends HTMLElement {
}
}
if (summaryPanel) {
summaryPanel.setAttribute('count', count);
this.updateProgress();
}
}
......@@ -388,6 +413,18 @@ class DisplayPanel extends HTMLElement {
}
return null;
}
/**
* Remove all panel items.
* @public
*/
removeAllPanelItems() {
for (const item of this.items_) {
item.remove();
}
this.items_ = [];
this.updateSummaryPanel();
}
}
window.customElements.define('xf-display-panel', DisplayPanel);
......@@ -283,9 +283,6 @@ class PanelItem extends HTMLElement {
let indicator = null;
/** @type {Element} */
let textNode;
if (oldValue === newValue) {
return;
}
// TODO(adanilo) Chop out each attribute handler into a function.
switch (name) {
case 'count':
......
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