diff --git a/angular/src/components/toastr.component.ts b/angular/src/components/toastr.component.ts
new file mode 100644
index 00000000000..07deb64eea2
--- /dev/null
+++ b/angular/src/components/toastr.component.ts
@@ -0,0 +1,85 @@
+import {
+ animate,
+ state,
+ style,
+ transition,
+ trigger
+} from '@angular/animations';
+import { CommonModule } from '@angular/common';
+import { Component, ModuleWithProviders, NgModule } from '@angular/core';
+import { DefaultNoComponentGlobalConfig, GlobalConfig, Toast as BaseToast, ToastPackage, ToastrService, TOAST_CONFIG } from 'ngx-toastr';
+
+@Component({
+ selector: '[toast-component2]',
+ template: `
+
+
+
+
+
+
+ {{ title }} [{{ duplicatesCount + 1 }}]
+
+
+
+
+ {{ message }}
+
+
+
+ `,
+ animations: [
+ trigger('flyInOut', [
+ state('inactive', style({ opacity: 0 })),
+ state('active', style({ opacity: 1 })),
+ state('removed', style({ opacity: 0 })),
+ transition(
+ 'inactive => active',
+ animate('{{ easeTime }}ms {{ easing }}')
+ ),
+ transition(
+ 'active => removed',
+ animate('{{ easeTime }}ms {{ easing }}')
+ ),
+ ]),
+ ],
+ preserveWhitespaces: false,
+})
+export class BitwardenToast extends BaseToast {
+ constructor(protected toastrService: ToastrService, public toastPackage: ToastPackage) {
+ super(toastrService, toastPackage);
+ }
+}
+
+export const BitwardenToastGlobalConfig: GlobalConfig = {
+ ...DefaultNoComponentGlobalConfig,
+ toastComponent: BitwardenToast,
+ };
+
+@NgModule({
+ imports: [CommonModule],
+ declarations: [BitwardenToast],
+ exports: [BitwardenToast],
+})
+export class BitwardenToastModule {
+ static forRoot(config: Partial = {}): ModuleWithProviders {
+ return {
+ ngModule: BitwardenToastModule,
+ providers: [
+ {
+ provide: TOAST_CONFIG,
+ useValue: {
+ default: BitwardenToastGlobalConfig,
+ config: config,
+ },
+ },
+ ],
+ };
+ }
+}
diff --git a/angular/src/services/jslib-services.module.ts b/angular/src/services/jslib-services.module.ts
index d398755fd66..2040fb1093e 100644
--- a/angular/src/services/jslib-services.module.ts
+++ b/angular/src/services/jslib-services.module.ts
@@ -3,7 +3,6 @@ import {
LOCALE_ID,
NgModule,
} from '@angular/core';
-import { ToasterModule } from 'angular2-toaster';
import { ApiService } from 'jslib-common/services/api.service';
import { AppIdService } from 'jslib-common/services/appId.service';
@@ -80,9 +79,6 @@ import { UnauthGuardService } from './unauth-guard.service';
import { ValidationService } from './validation.service';
@NgModule({
- imports: [
- ToasterModule,
- ],
declarations: [],
providers: [
{ provide: 'WINDOW', useValue: window },
diff --git a/common/src/abstractions/platformUtils.service.ts b/common/src/abstractions/platformUtils.service.ts
index 7f792e614b1..3b5562a6133 100644
--- a/common/src/abstractions/platformUtils.service.ts
+++ b/common/src/abstractions/platformUtils.service.ts
@@ -1,6 +1,10 @@
import { DeviceType } from '../enums/deviceType';
import { ThemeType } from '../enums/themeType';
+interface ToastOptions {
+ timeout?: number;
+}
+
export abstract class PlatformUtilsService {
identityClientId: string;
getDevice: () => DeviceType;
@@ -20,7 +24,7 @@ export abstract class PlatformUtilsService {
supportsWebAuthn: (win: Window) => boolean;
supportsDuo: () => boolean;
showToast: (type: 'error' | 'success' | 'warning' | 'info', title: string, text: string | string[],
- options?: any) => void;
+ options?: ToastOptions) => void;
showDialog: (body: string, title?: string, confirmText?: string, cancelText?: string,
type?: string, bodyIsHtml?: boolean) => Promise;
isDev: () => boolean;