report: render sub-rows in their own tr#10553
Conversation
| if (Array.isArray(values)) { | ||
| const subRowsElement = this._renderSubRows(values, subRowsHeading); | ||
| valueFragment.appendChild(subRowsElement); | ||
| if (!subRowHeadings.some(Boolean)) continue; |
There was a problem hiding this comment.
did you just reinvent a if (!subRowHeadings.length) conditional? 😎
There was a problem hiding this comment.
there is a return null; in the map
| const tbodyElem = this._dom.createChildOf(tableElem, 'tbody'); | ||
| for (const row of details.items) { | ||
| const rowElem = this._dom.createChildOf(tbodyElem, 'tr'); | ||
| // Render the main row. |
There was a problem hiding this comment.
can you split out into a _renderTableRow() method?
|
|
||
| // All sub-row data arrays should be the same length, but just in case they are not, | ||
| // determine the longest data array and fill the missing values with an | ||
| // null pair (which creates an empty cell). |
There was a problem hiding this comment.
adding nulls to create empty cells seems very weird to me.
its to maintain alignment with the parent headings right? but dont the parent headings already know what their subheadings are? can we use that relationship?
There was a problem hiding this comment.
background color only colors the width of the table if there is an element there.
There was a problem hiding this comment.
Paul refactor to remove the nulls here: subrow-layout...subrow-layout-by-col
I think most of the complexity in your and my impl. comes from trying to pass the values to this _renderRow function. How about instead the fn uses a callback? I think it'd look like this:
_renderRow(headings, heading => row && row[heading.key])
for i in numSubRow:
const subRowEl = _renderRow(headings, heading => row && Array.isArray(row[heading.key]) && row[heading.key][i])
...There was a problem hiding this comment.
yeah thats a nice solution. :)
There was a problem hiding this comment.
Peanut gallery: this seems like it's getting pretty involved for a static, self-generated table json of known width and height being turned into a <table> of known width and height. There's some table cruft we have to live with for legacy support, but subrows are brand new :)
Since (I don't believe) subrows are turned on anywhere yet (and we haven't shipped 6.0 yet regardless), maybe knowing more of the use case now gives a chance to step back and massage the data structure a bit to make dealing with them simpler? (#5 on the classic https://users.ece.utexas.edu/~adnan/pike.html)
| text-decoration: underline dotted #999; | ||
| } | ||
|
|
||
| .lh-sub-rows:not(:first-child) .lh-sub-row { |
There was a problem hiding this comment.
i kinda miss the previous styling.
i wonder if there's a way we can still have zebra striping on the non-subrows and the subrows feel like they belong.
... trying a few things out it seems impossible without way too much time. ah well.
There was a problem hiding this comment.
i kinda miss the previous styling.
I also prefer the previous styling. It's simple if the rendering code adds an "even" or "odd" class to all rows generated from a single data value. Then we just need to duplicate the CSS, one for both even / odd.
There was a problem hiding this comment.
It's simple if the rendering code adds an "even" or "odd" class to all rows generated from a single data value.
true! i don't mind that.
Co-Authored-By: Paul Irish <paulirish@google.com>
| subRowData.push({heading, value: values[i]}); | ||
| } | ||
|
|
||
| const rowEl = this._renderRow(subRowData); |
There was a problem hiding this comment.
just realized we got a renderTableRow() and a renderRow(). awkward.
maybe renderTableRow => buildTableItemRow ?
|
|
||
| // All sub-row data arrays should be the same length, but just in case they are not, | ||
| // determine the longest data array and fill the missing values with an | ||
| // null pair (which creates an empty cell). |
There was a problem hiding this comment.
yeah thats a nice solution. :)
|
Awaiting brendan's typecheck magic for subRows. Will enable a new details subrow shape. |
|
might also go with |
|
@brendankenny do you have an update on the types? If you can't devote any time in the next couple weeks can you possibly share what you've done so far so that I could prioritize it? |
I was hoping to iterate on this more, but lots of things have gotten in the way :) Maybe this is good enough or you can find some ways to improve. tl;dr: branch with audits and some of the tests converted to try out the proposal: master...subrowstraw The biggest constraint is what we identified in the beginning: since That means we can't have a unique The other constraint is for downstream renderers: ideally if a report renderer doesn't support subrows yet, they'll just silently be ignored. So, possible approaches:
After checking out (1) and not liking it, I tried out (2) and I'm reasonably happy. With this proposal, subrows become a bit more predictable (looking and acting exactly like Heart of things: /** A table item for rows that are nested within a top-level TableItem (row). */
export interface TableSubRows {
type: 'subrows';
items: TableItem[];
}
/** Possible types of values found within table items. */
type ItemValue = string | number | boolean | DebugData | NodeValue | SourceLocationValue | LinkValue | UrlValue | CodeValue | TableSubRows;
export interface TableItem {
debugData?: DebugData;
subRows?: TableSubRows;
[p: string]: undefined | ItemValue;
}and an item with subrows would look something like {
"url": "http://example.com/example.js",
"totalBytes": 71654,
"wastedBytes": 30470,
"wastedPercent": 42.52388078488413,
"subRows": {
"type": "subrows",
"items": [{
"sources": "...Control/assets/js/vendor/katex.min.js",
"sourceBytes": 14773,
"sourceWastedBytes": 500,
}, {
"//": "..."
}],
},
} |


Part of #10369
Before this change, the sub rows columns didn't align well with each other, except in perfect conditions (short names, wide viewport). This PR makes it so each sub-row is rendered in its own
trelement - the table layout does the alignment for us.narrow: