Skip to content

Commit

Permalink
Add confirmation toast after moving single password to the account
Browse files Browse the repository at this point in the history
This CL adds a confirmation toast that is visible after uploading a
single credential from the password details card entry.

Bug: 1503146
Change-Id: I434de73068a2eafec9ad9e3baa062ff2b9ab2878
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5169227
Reviewed-by: Viktor Semeniuk <vsemeniuk@google.com>
Reviewed-by: Vasilii Sukhanov <vasilii@chromium.org>
Commit-Queue: Karol Sygiet <sygiet@google.com>
Cr-Commit-Position: refs/heads/main@{#1244016}
  • Loading branch information
Karol Sygiet authored and Chromium LUCI CQ committed Jan 8, 2024
1 parent 6d0d01b commit 1e05b27
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 11 deletions.
3 changes: 3 additions & 0 deletions chrome/app/password_manager_ui_strings.grdp
Original file line number Diff line number Diff line change
Expand Up @@ -803,4 +803,7 @@
<message name="IDS_PASSWORD_MANAGER_UI_NO_USERNAME" desc="Placeholder on the username field when the username is empty.">
No username added
</message>
<message name="IDS_PASSWORD_MANAGER_UI_PASSWORD_MOVED_TOAST_MESSAGE" desc="Label for a toast dialog which indicates that a password was moved to the account storage">
Password saved in your Google Account, <ph name="USER_EMAIL"><ex>elisa.g.becket@gmail.com</ex>$1</ph>
</message>
</grit-part>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d0f8827b12b577312813cf7df4acf85a0bcab99a
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ export const PASSWORD_SHARE_BUTTON_BUTTON_ELEMENT_ID =

export type PasswordRemovedEvent =
CustomEvent<{removedFromStores: chrome.passwordsPrivate.PasswordStoreSet}>;
export type PasswordMovedEvent = CustomEvent<{accountEmail: string}>;

declare global {
interface HTMLElementEventMap {
'password-removed': PasswordRemovedEvent;
'password-moved': PasswordMovedEvent;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ export class MoveSinglePasswordDialogElement extends
assert(this.isOptedInForAccountStorage);
PasswordManagerImpl.getInstance().movePasswordsToAccount(
[this.password.id]);
this.dispatchEvent(new CustomEvent('password-moved', {
bubbles: true,
composed: true,
detail: {
accountEmail: this.accountEmail,
},
}));

this.$.dialog.close();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@
if="[[showPage(selectedPage_, pagesValueEnum_.PASSWORD_DETAILS)]]">
<password-details-section class="cr-centered-card-container"
on-password-removed="onPasswordRemoved_" prefs="{{prefs_}}"
on-passkey-removed="onPasskeyRemoved_">
on-passkey-removed="onPasskeyRemoved_"
on-password-moved="onPasswordMoved_">
</password-details-section>
</template>
</div>
Expand Down Expand Up @@ -145,7 +146,7 @@
<iron-media-query query="(max-width: 1200px)"
query-matches="{{collapsed_}}">
</iron-media-query>
<cr-toast id="removalToast" duration="5000">
<cr-toast id="toast" duration="5000">
<span id="removalNotification">[[toastMessage_]]</span>
<cr-button id="undo-removal" aria-label="$i18n{undoDescription}"
on-click="onUndoButtonClick_" hidden$="[[!showUndo_]]">
Expand Down
17 changes: 12 additions & 5 deletions chrome/browser/resources/password_manager/password_manager_app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import type {DomIf} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundle
import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';

import type {CheckupSectionElement} from './checkup_section.js';
import type {PasswordRemovedEvent} from './credential_details/password_details_card.js';
import type {PasswordMovedEvent, PasswordRemovedEvent} from './credential_details/password_details_card.js';
import type {FocusConfig} from './focus_config.js';
import {getTemplate} from './password_manager_app.html.js';
import {PasswordManagerImpl} from './password_manager_proxy.js';
Expand Down Expand Up @@ -63,7 +63,7 @@ export interface PasswordManagerAppElement {
drawerTemplate: DomIf,
passwords: PasswordsSectionElement,
prefs: SettingsPrefsElement,
removalToast: CrToastElement,
toast: CrToastElement,
settings: SettingsSectionElement,
sidebar: PasswordManagerSideBarElement,
toolbar: PasswordManagerToolbarElement,
Expand Down Expand Up @@ -276,18 +276,25 @@ export class PasswordManagerAppElement extends PasswordManagerAppElementBase {
// TODO(crbug.com/1350947): Show different message if account store user.
this.showUndo_ = true;
this.toastMessage_ = this.i18n('passwordDeleted');
this.$.removalToast.show();
this.$.toast.show();
}

private onPasskeyRemoved_() {
this.showUndo_ = false;
this.toastMessage_ = this.i18n('passkeyDeleted');
this.$.removalToast.show();
this.$.toast.show();
}

private onPasswordMoved_(event: PasswordMovedEvent) {
this.showUndo_ = false;
this.toastMessage_ =
this.i18n('passwordMovedToastMessage', event.detail.accountEmail);
this.$.toast.show();
}

private onUndoButtonClick_() {
PasswordManagerImpl.getInstance().undoRemoveSavedPasswordOrException();
this.$.removalToast.hide();
this.$.toast.hide();
}

private onSearchEnterClick_() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ content::WebUIDataSource* CreateAndAddPasswordsUIHTMLSource(
// depending on the build.
{"passwordManagerTitle",
IDS_PASSWORD_BUBBLES_PASSWORD_MANAGER_LINK_TEXT_SAVING_ON_DEVICE},
{"passwordMovedToastMessage",
IDS_PASSWORD_MANAGER_UI_PASSWORD_MOVED_TOAST_MESSAGE},
{"passwordNoteCharacterCount",
IDS_PASSWORD_MANAGER_UI_NOTE_CHARACTER_COUNT},
{"passwordNoteCharacterCountWarning",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ suite('PasswordManagerAppTest', function() {

await flushTasks();

assertFalse(app.$.removalToast.open);
assertFalse(app.$.toast.open);
const detailsSection =
app.shadowRoot!.querySelector('password-details-section');
assertTrue(!!detailsSection);
Expand All @@ -170,7 +170,7 @@ suite('PasswordManagerAppTest', function() {
},
}));

assertTrue(app.$.removalToast.open);
assertTrue(app.$.toast.open);
const undoButton =
app.shadowRoot!.querySelector<HTMLElement>('#undo-removal');
assertTrue(!!undoButton);
Expand All @@ -191,7 +191,7 @@ suite('PasswordManagerAppTest', function() {

await flushTasks();

assertFalse(app.$.removalToast.open);
assertFalse(app.$.toast.open);
const detailsSection =
app.shadowRoot!.querySelector('password-details-section');
assertTrue(!!detailsSection);
Expand All @@ -201,7 +201,7 @@ suite('PasswordManagerAppTest', function() {
composed: true,
}));

assertTrue(app.$.removalToast.open);
assertTrue(app.$.toast.open);

// The undo button should be hidden for passkeys.
const undoButton =
Expand All @@ -210,6 +210,41 @@ suite('PasswordManagerAppTest', function() {
assertTrue(undoButton.hidden);
});

test('Test password moved toast', async () => {
const testEmail = 'test.user@gmail.com';
const group = createCredentialGroup({
name: 'test.com',
credentials: [
createPasswordEntry({id: 0, username: 'test1'}),
],
});
Router.getInstance().navigateTo(Page.PASSWORD_DETAILS, group);

await flushTasks();

assertFalse(app.$.toast.open);
const detailsSection =
app.shadowRoot!.querySelector('password-details-section');
assertTrue(!!detailsSection);

detailsSection.dispatchEvent(new CustomEvent('password-moved', {
bubbles: true,
composed: true,
detail: {
accountEmail: testEmail,
},
}));

assertTrue(app.$.toast.open);
const undoButton =
app.shadowRoot!.querySelector<HTMLElement>('#undo-removal');
assertTrue(!!undoButton);
assertFalse(isVisible(undoButton));
assertTrue(app.$.toast.querySelector<HTMLElement>(
'#removalNotification')!.textContent!.trim()
.includes(testEmail));
});

test('import can be triggered from empty state', async function() {
// This is done to avoid flakiness.
Router.getInstance().navigateTo(Page.PASSWORDS);
Expand Down

0 comments on commit 1e05b27

Please sign in to comment.