Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add table list formatter for HTML audits #1505

Merged
merged 7 commits into from
Jan 25, 2017
Merged

Add table list formatter for HTML audits #1505

merged 7 commits into from
Jan 25, 2017

Conversation

ebidel
Copy link
Contributor

@ebidel ebidel commented Jan 21, 2017

R: all

This adds a new <table> formatter for HTML reports which increases clarity, fixes some overflow UI bugs we had with text, and will allow us to more easily add additional extended info in the future (e.g. extra properties from the gatherers, RUM data column, etc.)

An audit uses the formatter like so:

const createTable = Formatter.getByName('table').createTable;
...
extendedInfo: {
    formatter: Formatter.SUPPORTED_FORMATS.TABLE,
    value: {
      table: createTable({url: 'URL', protocol: 'Protocol'}, resources),
      results: resources
    }
}

Notes:

  • All the cells are overflow: auto so you can scroll them to reveal more of the url/code snippets
  • the original results are also being returned in extendedInfo so unit testing is easier and so we have the full objects as returned by the gatherer. Might want to change this in the future b/c it does mean the JSON results will be larger than they need to be.
  • This PR was getting big, so I only did 3 audits. When we're happy with this, we can move over other URLIST audits to use the TABLE formatter.

After:

screen shot 2017-01-20 at 2 01 54 pm

screen shot 2017-01-20 at 2 01 58 pm

screen shot 2017-01-20 at 2 02 01 pm

Before:

screen shot 2017-01-20 at 4 04 18 pm

screen shot 2017-01-20 at 4 04 24 pm

@patrickhulce
Copy link
Collaborator

Niiiiiiiiiiiice, I was needing something like this!

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome stuff!

results.push({
url,
total: `${originalKb} KB`,
webpSavings: `${webpSavings ? webpSavings.percent + '%' : ''}`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need the check here for webpSavings

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

url,
total: `${originalKb} KB`,
webpSavings: `${webpSavings ? webpSavings.percent + '%' : ''}`,
jpegSavings: `${jpegSavings ? jpegSavings.percent + '%' : ''}`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either add a check for it to be positive here or move jpegSavings = ... inside the if above?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably also move these out of `` strings :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

value: groupedResults
formatter: Formatter.SUPPORTED_FORMATS.TABLE,
value: {
results: groupedResults,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no changes needed to the mapping?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope. The table formatter will pull from thegroupedResults object as needed, based on the keys used in the first arg to createTable({url: 'URL', lineCol: 'Line/Col', type: 'Type', code: 'Snippet'}).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah so the extra info was already in there and was being ignored by URLLIST?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea.

<style>
.table_list {
margin-top: 8px;
border: 1px solid #EBEBEB;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we care about alphabetizing our rules?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a PR that alphabetizing selectors was brought up (can't find it now), but we deemed it unrealistic without tooling.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a-ok by me!

* @param {!Object<string, string>} headings for the table. The order of this
* object's key/value will be the order of the table's headings.
* @param {!Array<*>} results Audit results.
* @return {!{headings: string, rows: [{cols: [*]}]}} headings
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no ! needed, headings is Array<string> isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. done.

@ebidel
Copy link
Contributor Author

ebidel commented Jan 23, 2017

PTAL

@brendankenny
Copy link
Member

To keep formatting out of the audits (and avoiding the Formatter.getByName(Formatter.SUPPORTED_FORMATS.TABLE) monster), rather than have each audit access the createTable function, you could do something like add a

static getHelpers() {
  createTable
}

to the formatter, then have the extendedInfo be something like

extendedInfo: {
  formatter: Formatter.SUPPORTED_FORMATS.TABLE,
  value: {
    results,
    tableHeaders
  }
}

and then have createTable be applied to results in the partial to create the table at that point (and pretty could just call createTable inside itself)

WDYT?

@brendankenny
Copy link
Member

this is a huge improvement


/**
* Preps a formatted table (headings/col vals) for output.
* @param {!Object<string, string>} headings for the table. The order of this
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can just do !Object<string> (since all object keys are strings)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

const cols = headingKeys.map(key => {
switch (key) {
case 'code':
// Wrap code snippets in markdown ticks.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth documenting these special keys in jsdoc?

Copy link
Contributor Author

@ebidel ebidel Jan 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. added to the function description. If we ad more one-offs, that'll be easy to doc more.

* Preps a formatted table (headings/col vals) for output.
* @param {!Object<string, string>} headings for the table. The order of this
* object's key/value will be the order of the table's headings.
* @param {!Array<*>} results Audit results.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like you maybe expect this to be !Array<!Object>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* @param {!Object<string, string>} headings for the table. The order of this
* object's key/value will be the order of the table's headings.
* @param {!Array<*>} results Audit results.
* @return {{headings: Array<string>, rows: [{cols: [*]}]}} headings
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe @return {{headings: !Array<string>, rows: !Array<{cols: !Array<*>}>}}?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@ebidel
Copy link
Contributor Author

ebidel commented Jan 24, 2017

PTAL. getHelpers refactor and new tests.

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
┬─┬

@brendankenny brendankenny merged commit e1fc9e0 into master Jan 25, 2017
@brendankenny brendankenny deleted the tablelist branch January 25, 2017 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants