-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
report(details-renderer): support sub-rows within a table #10084
Conversation
@@ -548,7 +548,7 @@ describe('DetailsRenderer', () => { | |||
// itemType is overriden by code object | |||
headings: [{key: 'content', itemType: 'url', text: 'Heading'}], | |||
items: [ | |||
{content: {type: 'code', value: 'code object'}}, | |||
{content: {type: 'code', value: 'https://codeobject.com'}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback code in the details render will render a URL w/ an invalid url as a code
type - so, this test could possible have a false positive (if we ever refactored and broke the fallback type mechanism). This is avoided by using a valid URL as the value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pretty straightforward, nice!
🚲 🏠 : WDYT about subitems
instead of multi
, I had a difficult time at first understanding why the header definition was shaped the way it was until I got to the bit about valueElement
and the ChildElement
. subitems
, children
, something along those lines slightly better reflects the relationship IMO
Turns out that allowing any property of a audit product item to be an array does not complicate the renderer as much as I thought it would, so I removed it.
Does it still complicate protobuf story?
@@ -246,7 +246,7 @@ class DetailsRenderer { | |||
switch (heading.valueType) { | |||
case 'bytes': { | |||
const numValue = Number(value); | |||
return this._renderBytes({value: numValue, granularity: 1}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is unrelated to multi, right? just needed for the eventual js audits?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I noticed it when I was making the js audits. I could pull this out as a one line change. It seems like a mistake to me.
let multi; | ||
if (heading.multi) { | ||
multi = { | ||
key: heading.multi.key, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: would be nice to reuse this mapping bit rather than manually map since that's what the original point of the function was, but not big deal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, but had to disable some ts.
*/ | ||
_renderMultiValue(row, heading) { | ||
const values = row[heading.key]; | ||
if (!Array.isArray(values)) return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is always unexpected, right? any recovery options we have?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is mostly for ts. perhaps it should console.error
something.
I suppose we could wrap a scalar value in an array of one item - but I would rather be strict about what we accept here. If the heading key was misconfigured, the audit developer will surely notice before publishing (otherwise, the data won't ever show!) Same for if the row value is scalar instead of the expected array. Then there's the case where it, by some ungodly bug, is sometimes scalar, sometimes an array - I bet that won't ever happen, so I think we shouldn't bother with a fallback.
if (!Array.isArray(values)) return null; | ||
const valueElement = this._dom.createElement('div', 'lh-multi-values'); | ||
for (const childValue of values) { | ||
const childValueElement = this._renderTableValue(childValue, heading); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this actually work with arbitrary value types or is report css only setup to accept text/url/code/numbers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd expect it to work for any Value
types, although I've only used what you listed so far. For code
, the default pre
browser styles had to be tweaked (way too much whitespace). maybe others would need the same.
the |
how about subheading? |
Oh I'd definitely prefer |
ah, that's interesting, to me it seems like a good conceptual fit. before, each heading defined a single scalar type |
Oh, I mean I agree the thing we currently call |
big +1. also and yes at this point it'd make sense to rename |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in general i think this UI treatment provides extra data density that we can definitely use.
i like it.
that's fine but idk about splitting the terms here at this point. why not keep it consistent ( |
We're not splitting the terms, we use The fact you really like These are multiple values supplied at each individual row, right? AFAICT, we don't have any additional headings as a result of this PR, just additional data being rendered in each row, or is that wrong? |
Both the Paul and I drew some stuff on some paper and came up with a term we both like - |
we chatted about this a bit offline. i remembered that a design decision of ours was to make however but here i think we can afford to be quite explicit about how this new property will affect the visual representation. so (yes slightly weird that plurals Rows is not an array, but i also think it works) |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, what I like about this method of subRows too is that a renderer using the headings but doesn't know about subRows
will still be backwards compatible :)
/** | ||
* @param {LH.Audit.Details.Value[]} values | ||
* @param {LH.Audit.Details.OpportunityColumnHeading} heading | ||
* @return {Element?} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't this always return an element? why the ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it used to not :)
If a header defines a
mutli: { key: string}
property, the renderer will render each value initem[key]
within the same column of that row. All other properties (besides label - it doesn't apply) can be set for this "multi header" - anything not set defaults to the outerheading
.Note: Originally there was a toplevel
multi: {}
object, which contained all the keys that could be arrays. Turns out that allowing any property of a audit product item to be an array does not complicate the renderer as much as I thought it would, so I removed it.Examples
With this PR, nothing yet uses this feature. To see it in use, see the
bundle-analysis
branch (#10064)__