Skip to content

Commit 70b8a78

Browse files
ktranDevtools-frontend LUCI CQ
authored andcommitted
[GM3Restyling] Update private state tokens empty view
Before: https://i.imgur.com/hKZNNmL.png After: https://i.imgur.com/0iTBBmB.png Bug: 325443331 Change-Id: I660b2748218604d585ea69cac4eb7b499f4cd479 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6247614 Commit-Queue: Kim-Anh Tran <[email protected]> Reviewed-by: Kateryna Prokopenko <[email protected]>
1 parent 6b85ba0 commit 70b8a78

File tree

3 files changed

+68
-35
lines changed

3 files changed

+68
-35
lines changed

front_end/panels/application/components/TrustTokensView.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,14 @@ describeWithMockConnection('TrustTokensView', () => {
9494
]);
9595
});
9696

97-
it('hides trust token table when there are no trust tokens', async () => {
97+
it('shows empty state when there are no trust tokens', async () => {
9898
sinon.stub(target.storageAgent(), 'invoke_getTrustTokens').resolves({tokens: [], getError: () => undefined});
9999
const component = await renderTrustTokensView();
100100

101101
const nullGridElement = component.shadowRoot!.querySelector('devtools-data-grid-controller');
102102
assert.isNull(nullGridElement);
103103

104-
const noTrustTokensElement = component.shadowRoot!.querySelector('div.no-tt-message');
104+
const noTrustTokensElement = component.shadowRoot!.querySelector('.empty-state');
105105
assert.instanceOf(noTrustTokensElement, HTMLDivElement);
106106
});
107107

front_end/panels/application/components/TrustTokensView.ts

Lines changed: 64 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,26 @@ import type * as Protocol from '../../../generated/protocol.js';
1111
import * as Buttons from '../../../ui/components/buttons/buttons.js';
1212
import * as LegacyWrapper from '../../../ui/components/legacy_wrapper/legacy_wrapper.js';
1313
import * as RenderCoordinator from '../../../ui/components/render_coordinator/render_coordinator.js';
14+
// inspectorCommonStyles is imported for the empty state styling that is used for the start view
15+
// eslint-disable-next-line rulesdir/es-modules-import
16+
import inspectorCommonStylesRaw from '../../../ui/legacy/inspectorCommon.css.js';
17+
import * as UI from '../../../ui/legacy/legacy.js';
1418
import * as Lit from '../../../ui/lit/lit.js';
19+
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
1520

1621
import trustTokensViewStylesRaw from './trustTokensView.css.js';
1722

1823
// TODO(crbug.com/391381439): Fully migrate off of constructed style sheets.
1924
const trustTokensViewStyles = new CSSStyleSheet();
2025
trustTokensViewStyles.replaceSync(trustTokensViewStylesRaw.cssContent);
2126

27+
// TODO(crbug.com/391381439): Fully migrate off of constructed style sheets.
28+
const inspectorCommonStyles = new CSSStyleSheet();
29+
inspectorCommonStyles.replaceSync(inspectorCommonStylesRaw.cssContent);
30+
31+
const PRIVATE_STATE_TOKENS_EXPLANATION_URL =
32+
'https://developers.google.com/privacy-sandbox/protections/private-state-tokens';
33+
2234
const {html} = Lit;
2335

2436
const UIStrings = {
@@ -35,9 +47,14 @@ const UIStrings = {
3547
*/
3648
allStoredTrustTokensAvailableIn: 'All stored private state tokens available in this browser instance.',
3749
/**
38-
* @description Text shown instead of a table when the table would be empty.
50+
* @description Text shown instead of a table when the table would be empty. https://developers.google.com/privacy-sandbox/protections/private-state-tokens
3951
*/
40-
noTrustTokensStored: 'No private state tokens are currently stored.',
52+
noTrustTokens: 'No private state tokens detected',
53+
/**
54+
* @description Text shown if there are no private state tokens. https://developers.google.com/privacy-sandbox/protections/private-state-tokens
55+
*/
56+
trustTokensDescription:
57+
'On this page you can view all available private state tokens in the current browsing context.',
4158
/**
4259
* @description Each row in the Private State Token table has a delete button. This is the text shown
4360
* when hovering over this button. The placeholder is a normal URL, indicating the site which
@@ -49,6 +66,10 @@ const UIStrings = {
4966
* @description Heading label for a view. Previously known as 'Trust Tokens'.
5067
*/
5168
trustTokens: 'Private state tokens',
69+
/**
70+
* @description Text used in a link to learn more about the topic.
71+
*/
72+
learnMore: 'Learn more',
5273
};
5374
const str_ = i18n.i18n.registerUIStrings('panels/application/components/TrustTokensView.ts', UIStrings);
5475
export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -71,7 +92,7 @@ export class TrustTokensView extends LegacyWrapper.LegacyWrapper.WrappableCompon
7192

7293
connectedCallback(): void {
7394
this.wrapper?.contentElement.classList.add('vbox');
74-
this.#shadow.adoptedStyleSheets = [trustTokensViewStyles];
95+
this.#shadow.adoptedStyleSheets = [trustTokensViewStyles, inspectorCommonStyles];
7596
void this.render();
7697
}
7798

@@ -86,11 +107,7 @@ export class TrustTokensView extends LegacyWrapper.LegacyWrapper.WrappableCompon
86107
await RenderCoordinator.write('Render TrustTokensView', () => {
87108
// clang-format off
88109
Lit.render(html`
89-
<div>
90-
<span class="heading">${i18nString(UIStrings.trustTokens)}</span>
91-
<devtools-icon name="info" title=${i18nString(UIStrings.allStoredTrustTokensAvailableIn)}></devtools-icon>
92-
${this.#renderGridOrNoDataMessage(tokens)}
93-
</div>
110+
${this.#renderGridOrNoDataMessage(tokens)}
94111
`, this.#shadow, {host: this});
95112
// clang-format on
96113
if (this.isConnected) {
@@ -101,35 +118,49 @@ export class TrustTokensView extends LegacyWrapper.LegacyWrapper.WrappableCompon
101118

102119
#renderGridOrNoDataMessage(tokens: Protocol.Storage.TrustTokens[]): Lit.TemplateResult {
103120
if (tokens.length === 0) {
104-
return html`<div class="no-tt-message">${i18nString(UIStrings.noTrustTokensStored)}</div>`;
121+
// clang-format off
122+
return html`
123+
<div class="empty-state" jslog=${VisualLogging.section().context('empty-view')}>
124+
<div class="empty-state-header">${i18nString(UIStrings.noTrustTokens)}</div>
125+
<div class="empty-state-description">
126+
<span>${i18nString(UIStrings.trustTokensDescription)}</span>
127+
${UI.XLink.XLink.create(PRIVATE_STATE_TOKENS_EXPLANATION_URL, i18nString(UIStrings.learnMore), 'x-link', undefined, 'learn-more')}
128+
</div>
129+
</div>
130+
`;
131+
// clang-format on
105132
}
106133

107134
// clang-format off
108135
return html`
109-
<devtools-data-grid striped inline>
110-
<table>
111-
<tr>
112-
<th id="issuer" weight="10" sortable>${i18nString(UIStrings.issuer)}</th>
113-
<th id="count" weight="5" sortable>${i18nString(UIStrings.storedTokenCount)}</th>
114-
<th id="delete-button" weight="1" sortable></th>
115-
</tr>
116-
${tokens.filter(token => token.count > 0)
117-
.map(token => html`
118-
<tr>
119-
<td>${removeTrailingSlash(token.issuerOrigin)}</td>
120-
<td>${token.count}</td>
121-
<td>
122-
<devtools-button .iconName=${'bin'}
123-
.jslogContext=${'delete-all'}
124-
.size=${Buttons.Button.Size.SMALL}
125-
.title=${i18nString(UIStrings.deleteTrustTokens, {PH1: removeTrailingSlash(token.issuerOrigin)})}
126-
.variant=${Buttons.Button.Variant.ICON}
127-
@click=${this.#deleteClickHandler.bind(this, removeTrailingSlash(token.issuerOrigin))}></devtools-button>
128-
</td>
129-
</tr>
130-
`)}
131-
</table>
132-
</devtools-data-grid>
136+
<div>
137+
<span class="heading">${i18nString(UIStrings.trustTokens)}</span>
138+
<devtools-icon name="info" title=${i18nString(UIStrings.allStoredTrustTokensAvailableIn)}></devtools-icon>
139+
<devtools-data-grid striped inline>
140+
<table>
141+
<tr>
142+
<th id="issuer" weight="10" sortable>${i18nString(UIStrings.issuer)}</th>
143+
<th id="count" weight="5" sortable>${i18nString(UIStrings.storedTokenCount)}</th>
144+
<th id="delete-button" weight="1" sortable></th>
145+
</tr>
146+
${tokens.filter(token => token.count > 0)
147+
.map(token => html`
148+
<tr>
149+
<td>${removeTrailingSlash(token.issuerOrigin)}</td>
150+
<td>${token.count}</td>
151+
<td>
152+
<devtools-button .iconName=${'bin'}
153+
.jslogContext=${'delete-all'}
154+
.size=${Buttons.Button.Size.SMALL}
155+
.title=${i18nString(UIStrings.deleteTrustTokens, {PH1: removeTrailingSlash(token.issuerOrigin)})}
156+
.variant=${Buttons.Button.Variant.ICON}
157+
@click=${this.#deleteClickHandler.bind(this, removeTrailingSlash(token.issuerOrigin))}></devtools-button>
158+
</td>
159+
</tr>
160+
`)}
161+
</table>
162+
</devtools-data-grid>
163+
</div>
133164
`;
134165
// clang-format on
135166
}

front_end/panels/application/components/trustTokensView.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
:host {
88
padding: 20px;
9+
height: 100%;
10+
display: flex;
911
}
1012

1113
.heading {

0 commit comments

Comments
 (0)