mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-27 17:18:04 +01:00
[PM-147] Import error states usability improvements (#6245)
* Add import error dialog (cherry picked from commit518211dae0
) * Rename ErrorList to ErrorListItem (cherry picked from commita7dd643710
)
This commit is contained in:
parent
30d8168c2e
commit
2323509dee
@ -0,0 +1,29 @@
|
||||
<bit-dialog>
|
||||
<span bitDialogTitle>
|
||||
{{ "importError" | i18n }}
|
||||
</span>
|
||||
|
||||
<span bitDialogContent>
|
||||
<div>{{ "resolveTheErrorsBelowAndTryAgain" | i18n }}</div>
|
||||
<bit-table [dataSource]="dataSource">
|
||||
<ng-container header>
|
||||
<tr>
|
||||
<th bitCell>{{ "name" | i18n }}</th>
|
||||
<th bitCell>{{ "description" | i18n }}</th>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<ng-template body let-rows$>
|
||||
<tr bitRow *ngFor="let r of rows$ | async">
|
||||
<td bitCell>{{ r.type }}</td>
|
||||
<td bitCell>{{ r.message }}</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
</span>
|
||||
|
||||
<div bitDialogFooter>
|
||||
<button bitButton bitDialogClose buttonType="primary" type="button">
|
||||
{{ "ok" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
</bit-dialog>
|
@ -0,0 +1,33 @@
|
||||
import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog";
|
||||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
|
||||
import { TableDataSource } from "@bitwarden/components";
|
||||
|
||||
export interface ErrorListItem {
|
||||
type: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: "app-import-error-dialog",
|
||||
templateUrl: "./import-error-dialog.component.html",
|
||||
})
|
||||
export class ImportErrorDialogComponent implements OnInit {
|
||||
protected dataSource = new TableDataSource<ErrorListItem>();
|
||||
|
||||
constructor(public dialogRef: DialogRef, @Inject(DIALOG_DATA) public data: Error) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
const split = this.data.message.split("\n\n");
|
||||
if (split.length == 1) {
|
||||
this.dataSource.data = [{ type: "", message: this.data.message }];
|
||||
return;
|
||||
}
|
||||
|
||||
const data: ErrorListItem[] = [];
|
||||
split.forEach((line) => {
|
||||
data.push({ type: "", message: line });
|
||||
});
|
||||
this.dataSource.data = data;
|
||||
}
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
export * from "./import-error-dialog.component";
|
||||
export * from "./import-success-dialog.component";
|
||||
export * from "./file-password-prompt.component";
|
||||
|
@ -15,7 +15,11 @@ import {
|
||||
|
||||
import { LooseComponentsModule, SharedModule } from "../../shared";
|
||||
|
||||
import { ImportSuccessDialogComponent, FilePasswordPromptComponent } from "./dialog";
|
||||
import {
|
||||
ImportErrorDialogComponent,
|
||||
ImportSuccessDialogComponent,
|
||||
FilePasswordPromptComponent,
|
||||
} from "./dialog";
|
||||
import { ExportComponent } from "./export.component";
|
||||
import { ImportExportRoutingModule } from "./import-export-routing.module";
|
||||
import { ImportComponent } from "./import.component";
|
||||
@ -26,6 +30,7 @@ import { ImportComponent } from "./import.component";
|
||||
ImportComponent,
|
||||
ExportComponent,
|
||||
FilePasswordPromptComponent,
|
||||
ImportErrorDialogComponent,
|
||||
ImportSuccessDialogComponent,
|
||||
],
|
||||
providers: [
|
||||
|
@ -4,7 +4,6 @@ import { Router } from "@angular/router";
|
||||
import * as JSZip from "jszip";
|
||||
import { concat, Observable, Subject, lastValueFrom, combineLatest } from "rxjs";
|
||||
import { map, takeUntil } from "rxjs/operators";
|
||||
import Swal, { SweetAlertIcon } from "sweetalert2";
|
||||
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import {
|
||||
@ -31,7 +30,11 @@ import {
|
||||
ImportType,
|
||||
} from "@bitwarden/importer";
|
||||
|
||||
import { FilePasswordPromptComponent, ImportSuccessDialogComponent } from "./dialog";
|
||||
import {
|
||||
FilePasswordPromptComponent,
|
||||
ImportErrorDialogComponent,
|
||||
ImportSuccessDialogComponent,
|
||||
} from "./dialog";
|
||||
|
||||
@Component({
|
||||
selector: "app-import",
|
||||
@ -247,7 +250,9 @@ export class ImportComponent implements OnInit, OnDestroy {
|
||||
this.syncService.fullSync(true);
|
||||
await this.onSuccessfulImport();
|
||||
} catch (e) {
|
||||
this.error(e);
|
||||
this.dialogService.open<unknown, Error>(ImportErrorDialogComponent, {
|
||||
data: e,
|
||||
});
|
||||
this.logService.error(e);
|
||||
}
|
||||
}
|
||||
@ -303,27 +308,6 @@ export class ImportComponent implements OnInit, OnDestroy {
|
||||
this.fileSelected = fileInputEl.files.length > 0 ? fileInputEl.files[0] : null;
|
||||
}
|
||||
|
||||
private async error(error: Error) {
|
||||
await Swal.fire({
|
||||
heightAuto: false,
|
||||
buttonsStyling: false,
|
||||
icon: "error" as SweetAlertIcon,
|
||||
iconHtml: `<i class="swal-custom-icon bwi bwi-error text-danger"></i>`,
|
||||
input: "textarea",
|
||||
inputValue: error.message,
|
||||
inputAttributes: {
|
||||
readonly: "true",
|
||||
},
|
||||
titleText: this.i18nService.t("importError"),
|
||||
text: this.i18nService.t("importErrorDesc"),
|
||||
showConfirmButton: true,
|
||||
confirmButtonText: this.i18nService.t("ok"),
|
||||
onOpen: (popupEl) => {
|
||||
popupEl.querySelector(".swal2-textarea").scrollTo(0, 0);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private getFileContents(file: File): Promise<string> {
|
||||
if (this.format === "1password1pux") {
|
||||
return this.extractZipContent(file, "export.data");
|
||||
|
Loading…
Reference in New Issue
Block a user