1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 01:03:35 +00:00

[PM-1504] Migrate Dialogs to DialogService (#5013)

This PR introduces a generic `DialogService` which can be used by all the clients. This allows us to decouple dialogs from the `PlatformUtilsHelper`.

The `DialogService` provides a new method, `openSimpleDialog` which is the new interface for that type of dialogs.

This gives us 3 different implementations: 
- Web: DialogService modern dialogs
- Browser: SweetAlert
- Desktop: Native electron based
This commit is contained in:
Oscar Hinton
2023-05-02 18:46:03 +02:00
committed by GitHub
parent 7c4b2c04b9
commit 4e1867682f
144 changed files with 1514 additions and 1212 deletions

View File

@@ -3,6 +3,7 @@ import { FormBuilder } from "@angular/forms";
import { Observable, Subject } from "rxjs";
import { concatMap, debounceTime, filter, map, takeUntil, tap } from "rxjs/operators";
import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
@@ -109,7 +110,8 @@ export class SettingsComponent implements OnInit {
private cryptoService: CryptoService,
private modalService: ModalService,
private themingService: AbstractThemingService,
private settingsService: SettingsService
private settingsService: SettingsService,
private dialogService: DialogServiceAbstraction
) {
const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
@@ -295,13 +297,12 @@ export class SettingsComponent implements OnInit {
async saveVaultTimeout(newValue: number) {
if (newValue == null) {
const confirmed = await this.platformUtilsService.showDialog(
this.i18nService.t("neverLockWarning"),
"",
this.i18nService.t("yes"),
this.i18nService.t("cancel"),
"warning"
);
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "warning" },
content: { key: "neverLockWarning" },
type: SimpleDialogType.WARNING,
});
if (!confirmed) {
this.form.controls.vaultTimeout.setValue(this.previousVaultTimeout);
return;
@@ -332,13 +333,12 @@ export class SettingsComponent implements OnInit {
async saveVaultTimeoutAction(newValue: VaultTimeoutAction) {
if (newValue === "logOut") {
const confirmed = await this.platformUtilsService.showDialog(
this.i18nService.t("vaultTimeoutLogOutConfirmation"),
this.i18nService.t("vaultTimeoutLogOutConfirmationTitle"),
this.i18nService.t("yes"),
this.i18nService.t("cancel"),
"warning"
);
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "vaultTimeoutLogOutConfirmationTitle" },
content: { key: "vaultTimeoutLogOutConfirmation" },
type: SimpleDialogType.WARNING,
});
if (!confirmed) {
this.form.controls.vaultTimeoutAction.patchValue(VaultTimeoutAction.Lock, {
emitEvent: false,
@@ -462,13 +462,11 @@ export class SettingsComponent implements OnInit {
!this.form.value.enableTray &&
(this.form.value.startToTray || this.form.value.enableCloseToTray)
) {
const confirm = await this.platformUtilsService.showDialog(
this.i18nService.t("confirmTrayDesc"),
this.i18nService.t("confirmTrayTitle"),
this.i18nService.t("yes"),
this.i18nService.t("no"),
"warning"
);
const confirm = await this.dialogService.openSimpleDialog({
title: { key: "confirmTrayTitle" },
content: { key: "confirmTrayDesc" },
type: SimpleDialogType.WARNING,
});
if (confirm) {
this.form.controls.startToTray.setValue(false, { emitEvent: false });
@@ -524,35 +522,35 @@ export class SettingsComponent implements OnInit {
async saveBrowserIntegration() {
if (process.platform === "darwin" && !this.platformUtilsService.isMacAppStore()) {
await this.platformUtilsService.showDialog(
this.i18nService.t("browserIntegrationMasOnlyDesc"),
this.i18nService.t("browserIntegrationUnsupportedTitle"),
this.i18nService.t("ok"),
null,
"warning"
);
await this.dialogService.openSimpleDialog({
title: { key: "browserIntegrationUnsupportedTitle" },
content: { key: "browserIntegrationMasOnlyDesc" },
acceptButtonText: { key: "ok" },
cancelButtonText: null,
type: SimpleDialogType.WARNING,
});
this.form.controls.enableBrowserIntegration.setValue(false);
return;
} else if (isWindowsStore()) {
await this.platformUtilsService.showDialog(
this.i18nService.t("browserIntegrationWindowsStoreDesc"),
this.i18nService.t("browserIntegrationUnsupportedTitle"),
this.i18nService.t("ok"),
null,
"warning"
);
await this.dialogService.openSimpleDialog({
title: { key: "browserIntegrationUnsupportedTitle" },
content: { key: "browserIntegrationWindowsStoreDesc" },
acceptButtonText: { key: "ok" },
cancelButtonText: null,
type: SimpleDialogType.WARNING,
});
this.form.controls.enableBrowserIntegration.setValue(false);
return;
} else if (process.platform == "linux") {
await this.platformUtilsService.showDialog(
this.i18nService.t("browserIntegrationLinuxDesc"),
this.i18nService.t("browserIntegrationUnsupportedTitle"),
this.i18nService.t("ok"),
null,
"warning"
);
await this.dialogService.openSimpleDialog({
title: { key: "browserIntegrationUnsupportedTitle" },
content: { key: "browserIntegrationLinuxDesc" },
acceptButtonText: { key: "ok" },
cancelButtonText: null,
type: SimpleDialogType.WARNING,
});
this.form.controls.enableBrowserIntegration.setValue(false);
return;

View File

@@ -14,6 +14,7 @@ import { IndividualConfig, ToastrService } from "ngx-toastr";
import { firstValueFrom, Subject, takeUntil } from "rxjs";
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
import { ConfigServiceAbstraction } from "@bitwarden/common/abstractions/config/config.service.abstraction";
@@ -135,7 +136,8 @@ export class AppComponent implements OnInit, OnDestroy {
private policyService: InternalPolicyService,
private modalService: ModalService,
private keyConnectorService: KeyConnectorService,
private configService: ConfigServiceAbstraction
private configService: ConfigServiceAbstraction,
private dialogService: DialogServiceAbstraction
) {}
ngOnInit() {
@@ -231,12 +233,15 @@ export class AppComponent implements OnInit, OnDestroy {
const fingerprint = await this.cryptoService.getFingerprint(
await this.stateService.getUserId()
);
const result = await this.platformUtilsService.showDialog(
this.i18nService.t("yourAccountsFingerprint") + ":\n" + fingerprint.join("-"),
this.i18nService.t("fingerprintPhrase"),
this.i18nService.t("learnMore"),
this.i18nService.t("close")
);
const result = await this.dialogService.openSimpleDialog({
title: { key: "fingerprintPhrase" },
content:
this.i18nService.t("yourAccountsFingerprint") + ":\n" + fingerprint.join("-"),
acceptButtonText: { key: "learnMore" },
cancelButtonText: { key: "close" },
type: SimpleDialogType.INFO,
});
if (result) {
this.platformUtilsService.launchUri("https://bitwarden.com/help/fingerprint-phrase/");
}
@@ -265,24 +270,24 @@ export class AppComponent implements OnInit, OnDestroy {
});
break;
case "premiumRequired": {
const premiumConfirmed = await this.platformUtilsService.showDialog(
this.i18nService.t("premiumRequiredDesc"),
this.i18nService.t("premiumRequired"),
this.i18nService.t("learnMore"),
this.i18nService.t("cancel")
);
const premiumConfirmed = await this.dialogService.openSimpleDialog({
title: { key: "premiumRequired" },
content: { key: "premiumRequiredDesc" },
acceptButtonText: { key: "learnMore" },
type: SimpleDialogType.SUCCESS,
});
if (premiumConfirmed) {
await this.openModal<PremiumComponent>(PremiumComponent, this.premiumRef);
}
break;
}
case "emailVerificationRequired": {
const emailVerificationConfirmed = await this.platformUtilsService.showDialog(
this.i18nService.t("emailVerificationRequiredDesc"),
this.i18nService.t("emailVerificationRequired"),
this.i18nService.t("learnMore"),
this.i18nService.t("cancel")
);
const emailVerificationConfirmed = await this.dialogService.openSimpleDialog({
title: { key: "emailVerificationRequired" },
content: { key: "emailVerificationRequiredDesc" },
acceptButtonText: { key: "learnMore" },
type: SimpleDialogType.INFO,
});
if (emailVerificationConfirmed) {
this.platformUtilsService.launchUri(
"https://bitwarden.com/help/create-bitwarden-account/"

View File

@@ -3,6 +3,7 @@ import "zone.js";
// Register the locales for the application
import "./locales";
import { DialogModule } from "@angular/cdk/dialog";
import { NgModule } from "@angular/core";
import { ColorPasswordCountPipe } from "@bitwarden/angular/pipes/color-password-count.pipe";
@@ -56,7 +57,7 @@ import { EffluxDatesComponent as SendEffluxDatesComponent } from "./tools/send/e
import { SendComponent } from "./tools/send/send.component";
@NgModule({
imports: [SharedModule, AppRoutingModule, VaultFilterModule, LoginModule],
imports: [SharedModule, DialogModule, AppRoutingModule, VaultFilterModule, LoginModule],
declarations: [
AccessibilityCookieComponent,
AccountSwitcherComponent,

View File

@@ -1,5 +1,6 @@
import { APP_INITIALIZER, InjectionToken, NgModule } from "@angular/core";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import {
SECURE_STORAGE,
STATE_FACTORY,
@@ -43,6 +44,7 @@ import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "@
import { LoginGuard } from "../../auth/guards/login.guard";
import { Account } from "../../models/account";
import { ElectronCryptoService } from "../../services/electron-crypto.service";
import { ElectronDialogService } from "../../services/electron-dialog.service";
import { ElectronLogService } from "../../services/electron-log.service";
import { ElectronPlatformUtilsService } from "../../services/electron-platform-utils.service";
import { ElectronRendererMessagingService } from "../../services/electron-renderer-messaging.service";
@@ -176,6 +178,10 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
useClass: LoginService,
deps: [StateServiceAbstraction],
},
{
provide: DialogServiceAbstraction,
useClass: ElectronDialogService,
},
{
provide: CryptoServiceAbstraction,
useClass: ElectronCryptoService,

View File

@@ -3,6 +3,7 @@ import * as os from "os";
import { Component, OnInit } from "@angular/core";
import { UntypedFormBuilder } from "@angular/forms";
import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog";
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
@@ -33,7 +34,8 @@ export class ExportComponent extends BaseExportComponent implements OnInit {
formBuilder: UntypedFormBuilder,
private broadcasterService: BroadcasterService,
logService: LogService,
fileDownloadService: FileDownloadService
fileDownloadService: FileDownloadService,
dialogService: DialogServiceAbstraction
) {
super(
cryptoService,
@@ -46,7 +48,8 @@ export class ExportComponent extends BaseExportComponent implements OnInit {
logService,
userVerificationService,
formBuilder,
fileDownloadService
fileDownloadService,
dialogService
);
}
@@ -56,25 +59,23 @@ export class ExportComponent extends BaseExportComponent implements OnInit {
async warningDialog() {
if (this.encryptedFormat) {
return await this.platformUtilsService.showDialog(
this.i18nService.t("encExportKeyWarningDesc") +
return await this.dialogService.openSimpleDialog({
title: { key: "confirmVaultExport" },
content:
this.i18nService.t("encExportKeyWarningDesc") +
os.EOL +
os.EOL +
this.i18nService.t("encExportAccountWarningDesc"),
this.i18nService.t("confirmVaultExport"),
this.i18nService.t("exportVault"),
this.i18nService.t("cancel"),
"warning",
true
);
acceptButtonText: { key: "exportVault" },
type: SimpleDialogType.WARNING,
});
} else {
return await this.platformUtilsService.showDialog(
this.i18nService.t("exportWarningDesc"),
this.i18nService.t("confirmVaultExport"),
this.i18nService.t("exportVault"),
this.i18nService.t("cancel"),
"warning"
);
return await this.dialogService.openSimpleDialog({
title: { key: "confirmVaultExport" },
content: { key: "exportWarningDesc" },
acceptButtonText: { key: "exportVault" },
type: SimpleDialogType.WARNING,
});
}
}
}

View File

@@ -1,6 +1,7 @@
import { DatePipe } from "@angular/common";
import { Component } from "@angular/core";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { AddEditComponent as BaseAddEditComponent } from "@bitwarden/angular/tools/send/add-edit.component";
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
@@ -27,7 +28,8 @@ export class AddEditComponent extends BaseAddEditComponent {
messagingService: MessagingService,
policyService: PolicyService,
logService: LogService,
sendApiService: SendApiService
sendApiService: SendApiService,
dialogService: DialogServiceAbstraction
) {
super(
i18nService,
@@ -39,7 +41,8 @@ export class AddEditComponent extends BaseAddEditComponent {
policyService,
logService,
stateService,
sendApiService
sendApiService,
dialogService
);
}

View File

@@ -1,5 +1,6 @@
import { Component, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { SendComponent as BaseSendComponent } from "@bitwarden/angular/tools/send/send.component";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
@@ -46,7 +47,8 @@ export class SendComponent extends BaseSendComponent implements OnInit, OnDestro
policyService: PolicyService,
private searchBarService: SearchBarService,
logService: LogService,
sendApiService: SendApiService
sendApiService: SendApiService,
dialogService: DialogServiceAbstraction
) {
super(
sendService,
@@ -57,7 +59,8 @@ export class SendComponent extends BaseSendComponent implements OnInit, OnDestro
searchService,
policyService,
logService,
sendApiService
sendApiService,
dialogService
);
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
this.searchBarService.searchText$.subscribe((searchText) => {

View File

@@ -3,6 +3,7 @@ import { ActivatedRoute, Router } from "@angular/router";
import { ipcRenderer } from "electron";
import { LockComponent as BaseLockComponent } from "@bitwarden/angular/auth/components/lock.component";
import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
@@ -50,7 +51,8 @@ export class LockComponent extends BaseLockComponent {
policyService: InternalPolicyService,
passwordGenerationService: PasswordGenerationServiceAbstraction,
logService: LogService,
keyConnectorService: KeyConnectorService
keyConnectorService: KeyConnectorService,
dialogService: DialogServiceAbstraction
) {
super(
router,
@@ -68,7 +70,8 @@ export class LockComponent extends BaseLockComponent {
ngZone,
policyApiService,
policyService,
passwordGenerationService
passwordGenerationService,
dialogService
);
}
@@ -149,12 +152,11 @@ export class LockComponent extends BaseLockComponent {
}
if (await this.stateService.getBiometricUnlock()) {
const response = await this.platformUtilsService.showDialog(
this.i18nService.t("windowsBiometricUpdateWarning"),
this.i18nService.t("windowsBiometricUpdateWarningTitle"),
this.i18nService.t("yes"),
this.i18nService.t("no")
);
const response = await this.dialogService.openSimpleDialog({
title: { key: "windowsBiometricUpdateWarningTitle" },
content: { key: "windowsBiometricUpdateWarning" },
type: SimpleDialogType.WARNING,
});
await this.stateService.setBiometricRequirePasswordOnStart(response);
if (response) {

View File

@@ -3,6 +3,7 @@ import { UntypedFormBuilder } from "@angular/forms";
import { Router } from "@angular/router";
import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/components/register.component";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
@@ -38,7 +39,8 @@ export class RegisterComponent extends BaseRegisterComponent implements OnInit,
private broadcasterService: BroadcasterService,
private ngZone: NgZone,
logService: LogService,
auditService: AuditService
auditService: AuditService,
dialogService: DialogServiceAbstraction
) {
super(
formValidationErrorService,
@@ -53,7 +55,8 @@ export class RegisterComponent extends BaseRegisterComponent implements OnInit,
passwordGenerationService,
environmentService,
logService,
auditService
auditService,
dialogService
);
}

View File

@@ -2,6 +2,7 @@ import { Component, NgZone, OnDestroy } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { SetPasswordComponent as BaseSetPasswordComponent } from "@bitwarden/angular/components/set-password.component";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
@@ -39,7 +40,8 @@ export class SetPasswordComponent extends BaseSetPasswordComponent implements On
private ngZone: NgZone,
stateService: StateService,
organizationApiService: OrganizationApiServiceAbstraction,
organizationUserService: OrganizationUserService
organizationUserService: OrganizationUserService,
dialogService: DialogServiceAbstraction
) {
super(
i18nService,
@@ -55,7 +57,8 @@ export class SetPasswordComponent extends BaseSetPasswordComponent implements On
route,
stateService,
organizationApiService,
organizationUserService
organizationUserService,
dialogService
);
}

View File

@@ -0,0 +1,62 @@
import { ipcRenderer } from "electron";
import {
DialogService,
SimpleDialogOptions,
SimpleDialogType,
} from "@bitwarden/angular/services/dialog";
// Electron supports a limited set of dialog types
// https://www.electronjs.org/docs/latest/api/dialog#dialogshowmessageboxbrowserwindow-options
const electronTypeMap: Record<SimpleDialogType, string> = {
[SimpleDialogType.PRIMARY]: "info",
[SimpleDialogType.SUCCESS]: "info",
[SimpleDialogType.INFO]: "info",
[SimpleDialogType.WARNING]: "warning",
[SimpleDialogType.DANGER]: "error",
};
export class ElectronDialogService extends DialogService {
async openSimpleDialog(options: SimpleDialogOptions) {
const defaultCancel =
options.cancelButtonText === undefined
? options.acceptButtonText == null
? "no"
: "cancel"
: null;
return this.legacyShowDialog(
this.translate(options.content),
this.translate(options.title),
this.translate(options.acceptButtonText, "yes"),
this.translate(options.cancelButtonText, defaultCancel),
options.type
);
}
private async legacyShowDialog(
body: string,
title?: string,
confirmText?: string,
cancelText?: string,
type?: SimpleDialogType
) {
const buttons = [confirmText == null ? this.i18nService.t("ok") : confirmText];
if (cancelText != null) {
buttons.push(cancelText);
}
const result = await ipcRenderer.invoke("showMessageBox", {
type: electronTypeMap[type] ?? "none",
title: title,
message: title,
detail: body,
buttons: buttons,
cancelId: buttons.length === 2 ? 1 : null,
defaultId: 0,
noLink: true,
});
return Promise.resolve(result.response === 0);
}
}

View File

@@ -115,32 +115,6 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
});
}
async showDialog(
text: string,
title?: string,
confirmText?: string,
cancelText?: string,
type?: string
): Promise<boolean> {
const buttons = [confirmText == null ? this.i18nService.t("ok") : confirmText];
if (cancelText != null) {
buttons.push(cancelText);
}
const result = await ipcRenderer.invoke("showMessageBox", {
type: type,
title: title,
message: title,
detail: text,
buttons: buttons,
cancelId: buttons.length === 2 ? 1 : null,
defaultId: 0,
noLink: true,
});
return Promise.resolve(result.response === 0);
}
isDev(): boolean {
return isDev();
}

View File

@@ -1,5 +1,6 @@
import { Component } from "@angular/core";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { PremiumComponent as BasePremiumComponent } from "@bitwarden/angular/vault/components/premium.component";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
@@ -17,8 +18,9 @@ export class PremiumComponent extends BasePremiumComponent {
platformUtilsService: PlatformUtilsService,
apiService: ApiService,
logService: LogService,
stateService: StateService
stateService: StateService,
dialogService: DialogServiceAbstraction
) {
super(i18nService, platformUtilsService, apiService, logService, stateService);
super(i18nService, platformUtilsService, apiService, logService, stateService, dialogService);
}
}

View File

@@ -1,6 +1,7 @@
import { Component, NgZone, OnChanges, OnDestroy, ViewChild } from "@angular/core";
import { NgForm } from "@angular/forms";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { AddEditComponent as BaseAddEditComponent } from "@bitwarden/angular/vault/components/add-edit.component";
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
@@ -43,7 +44,8 @@ export class AddEditComponent extends BaseAddEditComponent implements OnChanges,
private ngZone: NgZone,
logService: LogService,
organizationService: OrganizationService,
sendApiService: SendApiService
sendApiService: SendApiService,
dialogService: DialogServiceAbstraction
) {
super(
cipherService,
@@ -59,7 +61,8 @@ export class AddEditComponent extends BaseAddEditComponent implements OnChanges,
logService,
passwordRepromptService,
organizationService,
sendApiService
sendApiService,
dialogService
);
}

View File

@@ -1,5 +1,6 @@
import { Component } from "@angular/core";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { AttachmentsComponent as BaseAttachmentsComponent } from "@bitwarden/angular/vault/components/attachments.component";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
@@ -23,7 +24,8 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
apiService: ApiService,
logService: LogService,
stateService: StateService,
fileDownloadService: FileDownloadService
fileDownloadService: FileDownloadService,
dialogService: DialogServiceAbstraction
) {
super(
cipherService,
@@ -34,7 +36,8 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
window,
logService,
stateService,
fileDownloadService
fileDownloadService,
dialogService
);
}
}

View File

@@ -1,5 +1,6 @@
import { Component } from "@angular/core";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { FolderAddEditComponent as BaseFolderAddEditComponent } from "@bitwarden/angular/vault/components/folder-add-edit.component";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
@@ -17,8 +18,16 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent {
folderApiService: FolderApiServiceAbstraction,
i18nService: I18nService,
platformUtilsService: PlatformUtilsService,
logService: LogService
logService: LogService,
dialogService: DialogServiceAbstraction
) {
super(folderService, folderApiService, i18nService, platformUtilsService, logService);
super(
folderService,
folderApiService,
i18nService,
platformUtilsService,
logService,
dialogService
);
}
}

View File

@@ -11,6 +11,7 @@ import { ActivatedRoute, Router } from "@angular/router";
import { first } from "rxjs/operators";
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { VaultFilter } from "@bitwarden/angular/vault/vault-filter/models/vault-filter.model";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@@ -100,7 +101,8 @@ export class VaultComponent implements OnInit, OnDestroy {
private passwordRepromptService: PasswordRepromptService,
private stateService: StateService,
private searchBarService: SearchBarService,
private apiService: ApiService
private apiService: ApiService,
private dialogService: DialogServiceAbstraction
) {}
async ngOnInit() {
@@ -679,13 +681,11 @@ export class VaultComponent implements OnInit, OnDestroy {
}
private async wantsToSaveChanges(): Promise<boolean> {
const confirmed = await this.platformUtilsService.showDialog(
this.i18nService.t("unsavedChangesConfirmation"),
this.i18nService.t("unsavedChangesTitle"),
this.i18nService.t("yes"),
this.i18nService.t("no"),
"warning"
);
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "unsavedChangesTitle" },
content: { key: "unsavedChangesConfirmation" },
type: SimpleDialogType.WARNING,
});
return !confirmed;
}

View File

@@ -7,6 +7,7 @@ import {
Output,
} from "@angular/core";
import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog";
import { ViewComponent as BaseViewComponent } from "@bitwarden/angular/vault/components/view.component";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
@@ -53,7 +54,8 @@ export class ViewComponent extends BaseViewComponent implements OnChanges {
passwordRepromptService: PasswordRepromptService,
logService: LogService,
stateService: StateService,
fileDownloadService: FileDownloadService
fileDownloadService: FileDownloadService,
dialogService: DialogServiceAbstraction
) {
super(
cipherService,
@@ -73,7 +75,8 @@ export class ViewComponent extends BaseViewComponent implements OnChanges {
passwordRepromptService,
logService,
stateService,
fileDownloadService
fileDownloadService,
dialogService
);
}
ngOnInit() {