[PM-7740] Create notifications settings component (navigational changes) (#8919)

* Move about.component into tools ownership

* Split out account security settings

Move settings.component.ts to auth/popup/settings and rename to account-security.component.ts
Move controls from settings.component.html and create account-security.component.html
Move settings.component.html to tools/popup/settings.component.html
Create settings.component.ts under tools/popup/settings
Fixup module imports and routing
Add new strings to en/message.json

* Move vault-timeout-input.component to auth

* Move await-desktop-dialog.component to auth

* Add transition for account-security

* Create notifications settings component

* Move excluded-domains component over to be owned by team-autofill

* Add notifications entry to settings screen

* Move excluded domains from settings to notifications settings screen

---------

Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
This commit is contained in:
Daniel James Smith 2024-05-08 21:04:41 +02:00 committed by GitHub
parent 7bb8caed42
commit 37d409578a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 170 additions and 12 deletions

View File

@ -3035,6 +3035,9 @@
"accountSecurity": { "accountSecurity": {
"message": "Account security" "message": "Account security"
}, },
"notifications": {
"message": "Notifications"
},
"appearance": { "appearance": {
"message": "Appearance" "message": "Appearance"
}, },

View File

@ -1,7 +1,7 @@
<form #form (ngSubmit)="submit()"> <form #form (ngSubmit)="submit()">
<header> <header>
<div class="left"> <div class="left">
<button type="button" routerLink="/tabs/settings"> <button type="button" routerLink="/notifications">
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span> <span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
<span>{{ "back" | i18n }}</span> <span>{{ "back" | i18n }}</span>
</button> </button>

View File

@ -8,8 +8,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { BrowserApi } from "../../platform/browser/browser-api"; import { BrowserApi } from "../../../platform/browser/browser-api";
import { enableAccountSwitching } from "../../platform/flags"; import { enableAccountSwitching } from "../../../platform/flags";
interface ExcludedDomain { interface ExcludedDomain {
uri: string; uri: string;

View File

@ -0,0 +1,89 @@
<header>
<div class="left">
<button type="button" routerLink="/tabs/settings">
<span class="header-icon"><i class="bwi bwi-angle-left" aria-hidden="true"></i></span>
<span>{{ "back" | i18n }}</span>
</button>
</div>
<h1 class="center">
<span class="title">{{ "notifications" | i18n }}</span>
</h1>
<div class="right">
<app-pop-out></app-pop-out>
</div>
</header>
<main tabindex="-1">
<div class="box">
<div class="box-content">
<div class="box-content-row box-content-row-checkbox" appBoxRow>
<label for="use-passkeys">{{ "enableUsePasskeys" | i18n }}</label>
<input
id="use-passkeys"
type="checkbox"
aria-describedby="use-passkeysHelp"
(change)="updateEnablePasskeys()"
[(ngModel)]="enablePasskeys"
/>
</div>
</div>
<div id="use-passkeysHelp" class="box-footer">
{{ "usePasskeysDesc" | i18n }}
</div>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row box-content-row-checkbox" appBoxRow>
<label for="addlogin-notification-bar">{{ "enableAddLoginNotification" | i18n }}</label>
<input
id="addlogin-notification-bar"
type="checkbox"
aria-describedby="addlogin-notification-barHelp"
(change)="updateAddLoginNotification()"
[(ngModel)]="enableAddLoginNotification"
/>
</div>
</div>
<div id="addlogin-notification-barHelp" class="box-footer">
{{
accountSwitcherEnabled
? ("addLoginNotificationDescAlt" | i18n)
: ("addLoginNotificationDesc" | i18n)
}}
</div>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row box-content-row-checkbox" appBoxRow>
<label for="changedpass-notification-bar">{{
"enableChangedPasswordNotification" | i18n
}}</label>
<input
id="changedpass-notification-bar"
type="checkbox"
aria-describedby="changedpass-notification-barHelp"
(change)="updateChangedPasswordNotification()"
[(ngModel)]="enableChangedPasswordNotification"
/>
</div>
</div>
<div id="changedpass-notification-barHelp" class="box-footer">
{{
accountSwitcherEnabled
? ("changedPasswordNotificationDescAlt" | i18n)
: ("changedPasswordNotificationDesc" | i18n)
}}
</div>
</div>
<div class="box list">
<div class="box-content single-line">
<button
type="button"
class="box-content-row box-content-row-flex text-default"
routerLink="/excluded-domains"
>
<div class="row-main">{{ "excludedDomains" | i18n }}</div>
<i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i>
</button>
</div>
</div>
</main>

View File

@ -0,0 +1,53 @@
import { Component, OnInit } from "@angular/core";
import { firstValueFrom } from "rxjs";
import { UserNotificationSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/user-notification-settings.service";
import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
import { enableAccountSwitching } from "../../../platform/flags";
@Component({
selector: "autofill-notification-settings",
templateUrl: "notifications.component.html",
})
export class NotifcationsSettingsComponent implements OnInit {
enableAddLoginNotification = false;
enableChangedPasswordNotification = false;
enablePasskeys = true;
accountSwitcherEnabled = false;
constructor(
private userNotificationSettingsService: UserNotificationSettingsServiceAbstraction,
private vaultSettingsService: VaultSettingsService,
) {
this.accountSwitcherEnabled = enableAccountSwitching();
}
async ngOnInit() {
this.enableAddLoginNotification = await firstValueFrom(
this.userNotificationSettingsService.enableAddedLoginPrompt$,
);
this.enableChangedPasswordNotification = await firstValueFrom(
this.userNotificationSettingsService.enableChangedPasswordPrompt$,
);
this.enablePasskeys = await firstValueFrom(this.vaultSettingsService.enablePasskeys$);
}
async updateAddLoginNotification() {
await this.userNotificationSettingsService.setEnableAddedLoginPrompt(
this.enableAddLoginNotification,
);
}
async updateChangedPasswordNotification() {
await this.userNotificationSettingsService.setEnableChangedPasswordPrompt(
this.enableChangedPasswordNotification,
);
}
async updateEnablePasskeys() {
await this.vaultSettingsService.setEnablePasskeys(this.enablePasskeys);
}
}

View File

@ -196,9 +196,6 @@ export const routerTransition = trigger("routerTransition", [
transition("vault-settings => sync", inSlideLeft), transition("vault-settings => sync", inSlideLeft),
transition("sync => vault-settings", outSlideRight), transition("sync => vault-settings", outSlideRight),
transition("tabs => excluded-domains", inSlideLeft),
transition("excluded-domains => tabs", outSlideRight),
transition("tabs => options", inSlideLeft), transition("tabs => options", inSlideLeft),
transition("options => tabs", outSlideRight), transition("options => tabs", outSlideRight),
@ -223,6 +220,13 @@ export const routerTransition = trigger("routerTransition", [
transition("tabs => edit-send, send-type => edit-send", inSlideUp), transition("tabs => edit-send, send-type => edit-send", inSlideUp),
transition("edit-send => tabs, edit-send => send-type", outSlideDown), transition("edit-send => tabs, edit-send => send-type", outSlideDown),
// Notification settings
transition("tabs => notifications", inSlideLeft),
transition("notifications => tabs", outSlideRight),
transition("notifications => excluded-domains", inSlideLeft),
transition("excluded-domains => notifications", outSlideRight),
transition("tabs => autofill", inSlideLeft), transition("tabs => autofill", inSlideLeft),
transition("autofill => tabs", outSlideRight), transition("autofill => tabs", outSlideRight),

View File

@ -27,6 +27,8 @@ import { TwoFactorOptionsComponent } from "../auth/popup/two-factor-options.comp
import { TwoFactorComponent } from "../auth/popup/two-factor.component"; import { TwoFactorComponent } from "../auth/popup/two-factor.component";
import { UpdateTempPasswordComponent } from "../auth/popup/update-temp-password.component"; import { UpdateTempPasswordComponent } from "../auth/popup/update-temp-password.component";
import { AutofillComponent } from "../autofill/popup/settings/autofill.component"; import { AutofillComponent } from "../autofill/popup/settings/autofill.component";
import { ExcludedDomainsComponent } from "../autofill/popup/settings/excluded-domains.component";
import { NotifcationsSettingsComponent } from "../autofill/popup/settings/notifications.component";
import { PremiumComponent } from "../billing/popup/settings/premium.component"; import { PremiumComponent } from "../billing/popup/settings/premium.component";
import BrowserPopupUtils from "../platform/popup/browser-popup-utils"; import BrowserPopupUtils from "../platform/popup/browser-popup-utils";
import { GeneratorComponent } from "../tools/popup/generator/generator.component"; import { GeneratorComponent } from "../tools/popup/generator/generator.component";
@ -56,7 +58,6 @@ import { VaultSettingsComponent } from "../vault/popup/settings/vault-settings.c
import { extensionRefreshRedirect, extensionRefreshSwap } from "./extension-refresh-route-utils"; import { extensionRefreshRedirect, extensionRefreshSwap } from "./extension-refresh-route-utils";
import { debounceNavigationGuard } from "./services/debounce-navigation.service"; import { debounceNavigationGuard } from "./services/debounce-navigation.service";
import { ExcludedDomainsComponent } from "./settings/excluded-domains.component";
import { HelpAndFeedbackComponent } from "./settings/help-and-feedback.component"; import { HelpAndFeedbackComponent } from "./settings/help-and-feedback.component";
import { OptionsComponent } from "./settings/options.component"; import { OptionsComponent } from "./settings/options.component";
import { TabsV2Component } from "./tabs-v2.component"; import { TabsV2Component } from "./tabs-v2.component";
@ -256,6 +257,12 @@ const routes: Routes = [
canActivate: [AuthGuard], canActivate: [AuthGuard],
data: { state: "account-security" }, data: { state: "account-security" },
}, },
{
path: "notifications",
component: NotifcationsSettingsComponent,
canActivate: [AuthGuard],
data: { state: "notifications" },
},
{ {
path: "vault-settings", path: "vault-settings",
component: VaultSettingsComponent, component: VaultSettingsComponent,

View File

@ -37,6 +37,8 @@ import { TwoFactorOptionsComponent } from "../auth/popup/two-factor-options.comp
import { TwoFactorComponent } from "../auth/popup/two-factor.component"; import { TwoFactorComponent } from "../auth/popup/two-factor.component";
import { UpdateTempPasswordComponent } from "../auth/popup/update-temp-password.component"; import { UpdateTempPasswordComponent } from "../auth/popup/update-temp-password.component";
import { AutofillComponent } from "../autofill/popup/settings/autofill.component"; import { AutofillComponent } from "../autofill/popup/settings/autofill.component";
import { ExcludedDomainsComponent } from "../autofill/popup/settings/excluded-domains.component";
import { NotifcationsSettingsComponent } from "../autofill/popup/settings/notifications.component";
import { PremiumComponent } from "../billing/popup/settings/premium.component"; import { PremiumComponent } from "../billing/popup/settings/premium.component";
import { HeaderComponent } from "../platform/popup/header.component"; import { HeaderComponent } from "../platform/popup/header.component";
import { PopupFooterComponent } from "../platform/popup/layout/popup-footer.component"; import { PopupFooterComponent } from "../platform/popup/layout/popup-footer.component";
@ -81,7 +83,6 @@ import { AppComponent } from "./app.component";
import { PopOutComponent } from "./components/pop-out.component"; import { PopOutComponent } from "./components/pop-out.component";
import { UserVerificationComponent } from "./components/user-verification.component"; import { UserVerificationComponent } from "./components/user-verification.component";
import { ServicesModule } from "./services/services.module"; import { ServicesModule } from "./services/services.module";
import { ExcludedDomainsComponent } from "./settings/excluded-domains.component";
import { HelpAndFeedbackComponent } from "./settings/help-and-feedback.component"; import { HelpAndFeedbackComponent } from "./settings/help-and-feedback.component";
import { OptionsComponent } from "./settings/options.component"; import { OptionsComponent } from "./settings/options.component";
import { TabsV2Component } from "./tabs-v2.component"; import { TabsV2Component } from "./tabs-v2.component";
@ -149,6 +150,7 @@ import "../platform/popup/locales";
LoginViaAuthRequestComponent, LoginViaAuthRequestComponent,
LoginDecryptionOptionsComponent, LoginDecryptionOptionsComponent,
OptionsComponent, OptionsComponent,
NotifcationsSettingsComponent,
AppearanceComponent, AppearanceComponent,
GeneratorComponent, GeneratorComponent,
PasswordGeneratorHistoryComponent, PasswordGeneratorHistoryComponent,

View File

@ -30,17 +30,17 @@
<button <button
type="button" type="button"
class="box-content-row box-content-row-flex text-default" class="box-content-row box-content-row-flex text-default"
routerLink="/vault-settings" routerLink="/notifications"
> >
<div class="row-main">{{ "vault" | i18n }}</div> <div class="row-main">{{ "notifications" | i18n }}</div>
<i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i> <i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i>
</button> </button>
<button <button
type="button" type="button"
class="box-content-row box-content-row-flex text-default" class="box-content-row box-content-row-flex text-default"
routerLink="/excluded-domains" routerLink="/vault-settings"
> >
<div class="row-main">{{ "excludedDomains" | i18n }}</div> <div class="row-main">{{ "vault" | i18n }}</div>
<i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i> <i class="bwi bwi-angle-right bwi-lg row-sub-icon" aria-hidden="true"></i>
</button> </button>
</div> </div>