Skip to content

Commit 13e64ed

Browse files
Update Grid with hardcoded links and more header rows.
Adds additional header rows (date, time, custom column headers), and links from cells (using a lit context; will be expanded in a follow-up). Also adds some other minor tweaks: - Update styling to make row and column headers sticky on the left and top (respectively) and fix a couple other nits. - Add minor unit tests and flesh out existing coverage. - Run `pnpm format` to fix some minor lint issues.
1 parent 1cfa658 commit 13e64ed

16 files changed

+3667
-3249
lines changed

web/.npmrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
shamefully-hoist=true
1+
public-hoist-pattern[]=*
2+
public-hoist-pattern[]=!*lit*

web/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121
},
2222
"dependencies": {
2323
"@lit-labs/router": "^0.1.1",
24+
"@lit/context": "^1.1.3",
2425
"@material/mwc-button": "^0.27.0",
2526
"@material/mwc-list": "^0.27.0",
2627
"@material/mwc-tab": "^0.27.0",
2728
"@material/mwc-tab-bar": "^0.27.0",
2829
"@protobuf-ts/plugin": "^2.8.3",
2930
"@web/test-runner-playwright": "^0.9.0",
3031
"json-server": "^0.17.3",
31-
"lit": "^2.7.0"
32+
"lit": "^3.2.1"
3233
},
3334
"devDependencies": {
3435
"@babel/preset-env": "^7.16.4",

web/pnpm-lock.yaml

Lines changed: 3330 additions & 3168 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/src/testgrid-context.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import {createContext} from '@lit/context';
2+
import { TestGridLinkTemplate } from './utils/link-template';
3+
4+
export { TestGridLinkTemplate } from './utils/link-template';
5+
export const linkContext = createContext<TestGridLinkTemplate>('testgrid-link-context');

web/src/testgrid-data-content.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import { LitElement, html, css } from 'lit';
33
import { customElement, property, state } from 'lit/decorators.js';
44
import { map } from 'lit/directives/map.js';
55
import { when } from 'lit/directives/when.js';
6+
import { provide } from '@lit/context';
67
import { navigateTab } from './utils/navigation.js';
78
import { ListDashboardTabsResponse } from './gen/pb/api/v1/data.js';
9+
import { type TestGridLinkTemplate, linkContext } from './testgrid-context.js';
810
import '@material/mwc-tab';
911
import '@material/mwc-tab-bar';
1012
import './testgrid-dashboard-summary';
@@ -17,6 +19,21 @@ import './testgrid-grid';
1719
@customElement('testgrid-data-content')
1820
// eslint-disable-next-line @typescript-eslint/no-unused-vars
1921
export class TestgridDataContent extends LitElement {
22+
static styles = css`
23+
:host {
24+
display: grid;
25+
grid-template-rows: minmax(1em, auto) minmax(0, 100%);
26+
width: 100%;
27+
height: 100%;
28+
}
29+
30+
mwc-tab {
31+
--mdc-typography-button-letter-spacing: 0;
32+
--mdc-tab-horizontal-padding: 12px;
33+
--mdc-typography-button-font-size: 0.8rem;
34+
}
35+
`;
36+
2037
@state()
2138
tabNames: string[] = [];
2239

@@ -32,6 +49,9 @@ export class TestgridDataContent extends LitElement {
3249
@property({ type: String })
3350
tabName?: string;
3451

52+
@provide({ context: linkContext })
53+
linkTemplate: TestGridLinkTemplate = { url: new URL('https://prow.k8s.io/') };
54+
3555
// set the functionality when any tab is clicked on
3656
private onTabActivated(event: CustomEvent<{ index: number }>) {
3757
const tabIndex = event.detail.index;
@@ -84,6 +104,7 @@ export class TestgridDataContent extends LitElement {
84104
when(
85105
this.tabNames.length > 0,
86106
() => html` <mwc-tab-bar
107+
style="width: 100vw"
87108
.activeIndex=${this.activeIndex}
88109
@MDCTabBar:activated="${this.onTabActivated}"
89110
>
@@ -116,7 +137,9 @@ export class TestgridDataContent extends LitElement {
116137
if (!response.ok) {
117138
throw new Error(`HTTP error: ${response.status}`);
118139
}
119-
const data = ListDashboardTabsResponse.fromJson(await response.json());
140+
const data = ListDashboardTabsResponse.fromJson(await response.json(), {
141+
ignoreUnknownFields: true,
142+
});
120143
const tabNames: string[] = ['Summary'];
121144
data.dashboardTabs.forEach(tab => {
122145
tabNames.push(tab.name);
@@ -139,12 +162,4 @@ export class TestgridDataContent extends LitElement {
139162
this.activeIndex = index;
140163
}
141164
}
142-
143-
static styles = css`
144-
mwc-tab {
145-
--mdc-typography-button-letter-spacing: 0;
146-
--mdc-tab-horizontal-padding: 12px;
147-
--mdc-typography-button-font-size: 0.8rem;
148-
}
149-
`;
150165
}

web/src/testgrid-grid-cell.ts

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import { LitElement, html, css } from "lit";
2-
import { customElement, property } from "lit/decorators.js";
1+
import { LitElement, html, css } from 'lit';
2+
import {consume} from '@lit/context';
3+
import { customElement, property } from 'lit/decorators.js';
4+
import { linkContext, TestGridLinkTemplate } from './testgrid-context';
35

46
@customElement('testgrid-grid-cell')
5-
export class TestgridGridCell extends LitElement{
6-
// Styling for status attribute corresponds to test_status.proto enum.
7-
static styles = css`
7+
export class TestgridGridCell extends LitElement {
8+
// Styling for status attribute corresponds to test_status.proto enum.
9+
static styles = css`
810
:host {
911
min-width: 80px;
1012
width: 80px;
@@ -23,46 +25,69 @@ export class TestgridGridCell extends LitElement{
2325
font-size: 12px;
2426
}
2527
26-
:host([status="NO_RESULT"]) {
27-
background-color: transparent;
28+
:host([status='NO_RESULT']) {
29+
background-color: transparent;
2830
}
2931
30-
:host([status="PASS"]), :host([status="PASS_WITH_ERRORS"]) {
31-
background-color: #4d7;
32-
color: #273;
32+
:host([status='PASS']),
33+
:host([status='PASS_WITH_ERRORS']) {
34+
background-color: #4d7;
35+
color: #273;
3336
}
3437
35-
:host([status="PASS_WITH_SKIPS"]), :host([status="BUILD_PASSED"]) {
36-
background-color: #bfd;
37-
color: #465;
38+
:host([status='PASS_WITH_SKIPS']),
39+
:host([status='BUILD_PASSED']) {
40+
background-color: #bfd;
41+
color: #465;
3842
}
3943
40-
:host([status="RUNNING"]), :host([status="CATEGORIZED_ABORT"]), :host([status="UNKNOWN"]), :host([status="CANCEL"]), :host([status="BLOCKED"]) {
41-
background-color: #ccd;
42-
color: #446;
44+
:host([status='RUNNING']),
45+
:host([status='CATEGORIZED_ABORT']),
46+
:host([status='UNKNOWN']),
47+
:host([status='CANCEL']),
48+
:host([status='BLOCKED']) {
49+
background-color: #ccd;
50+
color: #446;
4351
}
4452
45-
:host([status="TIMED_OUT"]), :host([status="CATEGORIZED_FAIL"]), :host([status="FAIL"]), :host([status="FLAKY"]) {
46-
background-color: #a24;
47-
color: #fdd;
53+
:host([status='TIMED_OUT']),
54+
:host([status='CATEGORIZED_FAIL']),
55+
:host([status='FAIL']),
56+
:host([status='FLAKY']) {
57+
background-color: #a24;
58+
color: #fdd;
4859
}
4960
50-
:host([status="BUILD_FAIL"]) {
51-
background-color: #111;
52-
color: #ddd;
61+
:host([status='BUILD_FAIL']) {
62+
background-color: #111;
63+
color: #ddd;
5364
}
5465
55-
:host([status="FLAKY"]) {
56-
background-color: #63a;
57-
color: #dcf;
66+
:host([status='FLAKY']) {
67+
background-color: #63a;
68+
color: #dcf;
69+
}
70+
71+
a {
72+
text-decoration: inherit;
73+
color: inherit;
74+
width: 100%;
75+
height: 100%;
5876
}
5977
`;
6078

61-
@property({reflect: true, attribute: 'status'}) status: String;
79+
@property({ reflect: true, attribute: 'status' }) status: string;
80+
81+
@property() icon: string;
6282

63-
@property() icon: String;
83+
@consume({context: linkContext})
84+
@property({attribute: false})
85+
public linkTemplate?: TestGridLinkTemplate;
6486

65-
render(){
66-
return html`${this.icon}`;
87+
render() {
88+
if (this.linkTemplate == undefined) {
89+
return html `<span>${this.icon}</span>`
6790
}
91+
return html`<a href="${this.linkTemplate.url.toString()}"><span>${this.icon}</span></a>`;
92+
}
6893
}
Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { LitElement, html, css } from "lit";
2-
import { customElement, property } from "lit/decorators.js";
1+
import { LitElement, html, css } from 'lit';
2+
import { styleMap } from 'lit/directives/style-map.js';
3+
import { customElement, property } from 'lit/decorators.js';
34

45
@customElement('testgrid-grid-column-header')
5-
export class TestgridGridColumnHeader extends LitElement{
6-
// TODO(michelle192837): Collate column headers with the same value.
7-
static styles = css`
6+
export class TestgridGridColumnHeader extends LitElement {
7+
static styles = css`
88
:host {
99
text-align: center;
1010
font-family: Roboto, Verdana, sans-serif;
@@ -13,20 +13,24 @@ export class TestgridGridColumnHeader extends LitElement{
1313
color: #224;
1414
min-height: 22px;
1515
max-height: 22px;
16-
max-width: 80px;
17-
width:80px;
18-
min-width: 80px;
19-
padding: .1em .3em;
16+
padding: 0.1em 0.3em;
2017
box-sizing: border-box;
21-
white-space:nowrap;
18+
white-space: nowrap;
2219
overflow-x: hidden;
2320
text-overflow: ellipsis;
2421
}
22+
span {
23+
position: sticky;
24+
left: 0;
25+
right: 0;
26+
width: fit-content;
27+
margin: auto;
28+
}
2529
`;
2630

27-
@property() name: String;
31+
@property() value: string;
2832

29-
render(){
30-
return html`${this.name}`;
31-
}
33+
render() {
34+
return html`<span>${this.value}</span>`;
35+
}
3236
}

web/src/testgrid-grid-header-row.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import { LitElement, html, css } from 'lit';
22
import { map } from 'lit/directives/map.js';
3+
import { styleMap } from 'lit/directives/style-map.js';
34
import { customElement, property } from 'lit/decorators.js';
4-
import { ListHeadersResponse } from './gen/pb/api/v1/data.js';
55
import './testgrid-grid-row-name';
66
import './testgrid-grid-column-header';
77

8+
// CombinedHeader represents a header element that spans multiple columns
9+
// (when a header value is repeated multiple times in a row).
10+
export interface CombinedHeader {
11+
value: string;
12+
count: number;
13+
}
14+
815
@customElement('testgrid-grid-header-row')
916
export class TestgridGridHeaderRow extends LitElement {
1017
static styles = css`
@@ -15,21 +22,31 @@ export class TestgridGridHeaderRow extends LitElement {
1522
flex-flow: row nowrap;
1623
gap: 0px 2px;
1724
margin: 2px;
25+
width: fit-content;
1826
}
1927
`;
2028

21-
@property() headers: ListHeadersResponse;
29+
@property() name: string;
30+
31+
@property() combinedHeaders: CombinedHeader[];
2232

2333
render() {
24-
// TODO(michelle192837): Replace row name component with more appropriate one.
34+
const nameStyles = {background: '#ededed', zIndex: '20'};
2535
return html`
26-
<testgrid-grid-row-name></testgrid-grid-row-name>
36+
<testgrid-grid-row-name .name="${this.name}" style=${styleMap(nameStyles)}></testgrid-grid-row-name>
2737
${map(
28-
this.headers?.headers,
29-
header =>
30-
html`<testgrid-grid-column-header
31-
.name="${header.build}"
32-
></testgrid-grid-column-header>`
38+
this.combinedHeaders,
39+
header => {
40+
// TODO(michelle192837): Stop hardcoding header width.
41+
const width = `${ (header.count - 1) * (80 + 2) + 80 }px`
42+
const styles = {width, minWidth: width, maxWidth: width};
43+
return html`
44+
<testgrid-grid-column-header
45+
style=${styleMap(styles)}
46+
.value="${header.value}"
47+
></testgrid-grid-column-header>
48+
`
49+
}
3350
)}
3451
`;
3552
}

0 commit comments

Comments
 (0)