1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

[PM-9051][PM-8641] Use reusable export-component on web (#9741)

* Add export-web.component

Introduce new export-web component
Delete old component
export.module - With export-web being standalone there's no need for a importModule
Change routing to load new component

* Prepare export.component to receive a orgId via the hosting-component

* Remove unused onSaved as it's replaced by onSuccessfulExport

* Refactor org-vault-export.component

Introduce new org-vault-export.component.html as the old component relied on the markup from password manager
Refactor org-vault-export.component
Retrieve organizationId from Route and pass it into the shared export.component
Ensure when exporting from AC to include all data from the selected org
org-vault-export.module - With the new component being standalone there's no need for a importModule
Change routing to load new org-vault-export component

* PM-8641 - Add success toast to base-export component
This ensures a success toast is shown on all clients consistently
Add missing entries into clients messages.json

---------

Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
This commit is contained in:
Daniel James Smith
2024-06-25 19:17:03 +02:00
committed by GitHub
parent 9ec01422df
commit c35bbc522c
15 changed files with 138 additions and 329 deletions

View File

@@ -1,5 +1,13 @@
import { CommonModule } from "@angular/common";
import { Component, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from "@angular/core";
import {
Component,
EventEmitter,
Input,
OnDestroy,
OnInit,
Output,
ViewChild,
} from "@angular/core";
import { ReactiveFormsModule, UntypedFormBuilder, Validators } from "@angular/forms";
import { map, merge, Observable, startWith, Subject, takeUntil } from "rxjs";
@@ -53,6 +61,26 @@ import { ExportScopeCalloutComponent } from "./export-scope-callout.component";
],
})
export class ExportComponent implements OnInit, OnDestroy {
private _organizationId: string;
get organizationId(): string {
return this._organizationId;
}
/**
* Enables the hosting control to pass in an organizationId
* If a organizationId is provided, the organization selection is disabled.
*/
@Input() set organizationId(value: string) {
this._organizationId = value;
this.organizationService
.get$(this._organizationId)
.pipe(takeUntil(this.destroy$))
.subscribe((organization) => {
this._organizationId = organization?.id;
});
}
/**
* The hosting control also needs a bitSubmitDirective (on the Submit button) which calls this components {@link submit}-method.
* This components formState (loading/disabled) is emitted back up to the hosting component so for example the Submit button can be enabled/disabled and show loading state.
@@ -82,7 +110,6 @@ export class ExportComponent implements OnInit, OnDestroy {
@Output()
onSuccessfulExport = new EventEmitter<string>();
@Output() onSaved = new EventEmitter();
@ViewChild(PasswordStrengthComponent) passwordStrengthComponent: PasswordStrengthComponent;
encryptedExportType = EncryptedExportType;
@@ -91,7 +118,6 @@ export class ExportComponent implements OnInit, OnDestroy {
filePasswordValue: string = null;
private _disabledByPolicy = false;
protected organizationId: string = null;
organizations$: Observable<Organization[]>;
protected get disabledByPolicy(): boolean {
@@ -120,6 +146,7 @@ export class ExportComponent implements OnInit, OnDestroy {
];
private destroy$ = new Subject<void>();
private onlyManagedCollections = true;
constructor(
protected i18nService: I18nService,
@@ -163,6 +190,8 @@ export class ExportComponent implements OnInit, OnDestroy {
);
this.exportForm.controls.vaultSelector.patchValue(this.organizationId);
this.exportForm.controls.vaultSelector.disable();
this.onlyManagedCollections = false;
return;
}
@@ -211,7 +240,12 @@ export class ExportComponent implements OnInit, OnDestroy {
try {
const data = await this.getExportData();
this.downloadFile(data);
this.saved();
this.toastService.showToast({
variant: "success",
title: null,
message: this.i18nService.t("exportSuccess"),
});
this.onSuccessfulExport.emit(this.organizationId);
await this.collectEvent();
this.exportForm.get("secret").setValue("");
this.exportForm.clearValidators();
@@ -252,11 +286,6 @@ export class ExportComponent implements OnInit, OnDestroy {
await this.doExport();
};
protected saved() {
this.onSaved.emit();
this.onSuccessfulExport.emit(this.organizationId);
}
private async verifyUser(): Promise<boolean> {
let confirmDescription = "exportWarningDesc";
if (this.isFileEncryptedExport) {
@@ -298,7 +327,7 @@ export class ExportComponent implements OnInit, OnDestroy {
this.organizationId,
this.format,
this.filePassword,
true,
this.onlyManagedCollections,
);
}