mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-21 16:18:28 +01:00
[PM-4197] Enable importing on deskop (#6502)
* Split up import/export into separate modules * Fix routing and apply PR feedback * Renamed OrganizationExport exports to OrganizationVaultExport * Make import dialogs standalone and move them to libs/importer * Make import.component re-usable - Move functionality which was previously present on the org-import.component into import.component - Move import.component into libs/importer Make import.component standalone Create import-web.component to represent Web UI Fix module imports and routing Remove unused org-import-files * Enable importing on deskop Create import-dialog Create file-menu entry to open import-dialog Extend messages.json to include all the necessary messages from shared components * Renamed filenames according to export rename * Make ImportWebComponent standalone, simplify routing * Pass organizationId as Input to ImportComponent * use formLoading and formDisabled outputs * use formLoading & formDisabled in desktop * Emit an event when the import succeeds Remove Angular router from base-component as other clients might not have routing (i.e. desktop) Move logic that happened on web successful import into the import-web.component * Enable importing on deskop Create import-dialog Create file-menu entry to open import-dialog Extend messages.json to include all the necessary messages from shared components * use formLoading & formDisabled in desktop * Add missing message for importBlockedByPolicy callout * Remove commented code for submit button * Implement onSuccessfulImport to close dialog on success * fix table themes on desktop & browser * fix fileSelector button styles * update selectors to use tools prefix; remove unused selectors * update selectors * Wall off UI components in libs/importer Create barrel-file for libs/importer/components Remove components and dialog exports from libs/importer/index.ts Extend libs/shared/tsconfig.libs.json to include @bitwarden/importer/ui -> libs/importer/components Extend apps/web/tsconfig.ts to include @bitwarden/importer/ui Update all usages * Rename @bitwarden/importer to @bitwarden/importer/core Create more barrel files in libs/importer/* Update imports within libs/importer Extend tsconfig files Update imports in web, desktop, browser and cli * Lazy-load the ImportWebComponent via both routes * Fix import path for ImportComponent * Use SharedModule as import in import-web.component * File selector should be displayed as secondary * Add missing messages for file-password-prompt * Add missing messages for import-error-dialog * Add missing message for import-success-dialog * Use bitSubmit to override submit preventDefault (#6607) Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com> * Use large dialogSize * PM-4398 - Add missing importWarning --------- Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com> Co-authored-by: William Martin <contact@willmartian.com>
This commit is contained in:
parent
9e290a3fed
commit
e357819251
@ -55,6 +55,7 @@ import { FolderAddEditComponent } from "../vault/app/vault/folder-add-edit.compo
|
||||
import { SettingsComponent } from "./accounts/settings.component";
|
||||
import { ExportComponent } from "./tools/export/export.component";
|
||||
import { GeneratorComponent } from "./tools/generator.component";
|
||||
import { ImportDesktopComponent } from "./tools/import/import-desktop.component";
|
||||
import { PasswordGeneratorHistoryComponent } from "./tools/password-generator-history.component";
|
||||
|
||||
const BroadcasterSubscriptionId = "AppComponent";
|
||||
@ -328,6 +329,9 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
this.messagingService.send("scheduleNextSync");
|
||||
break;
|
||||
case "importVault":
|
||||
await this.dialogService.open(ImportDesktopComponent);
|
||||
break;
|
||||
case "exportVault":
|
||||
await this.openExportVault();
|
||||
break;
|
||||
|
@ -0,0 +1,26 @@
|
||||
<bit-dialog #dialog dialogSize="large">
|
||||
<span bitDialogTitle>{{ "importData" | i18n }}</span>
|
||||
<ng-container bitDialogContent>
|
||||
<tools-import
|
||||
(formLoading)="this.loading = $event"
|
||||
(formDisabled)="this.disabled = $event"
|
||||
(onSuccessfulImport)="this.onSuccessfulImport($event)"
|
||||
></tools-import>
|
||||
</ng-container>
|
||||
<ng-container bitDialogFooter>
|
||||
<button
|
||||
[disabled]="disabled"
|
||||
[loading]="loading"
|
||||
form="importForm"
|
||||
bitButton
|
||||
type="submit"
|
||||
bitFormButton
|
||||
buttonType="primary"
|
||||
>
|
||||
{{ "importData" | i18n }}
|
||||
</button>
|
||||
<button type="button" bitButton bitFormButton buttonType="secondary" bitDialogClose>
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
@ -0,0 +1,33 @@
|
||||
import { DialogRef } from "@angular/cdk/dialog";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { AsyncActionsModule, ButtonModule, DialogModule } from "@bitwarden/components";
|
||||
import { ImportComponent } from "@bitwarden/importer/ui";
|
||||
|
||||
@Component({
|
||||
templateUrl: "import-desktop.component.html",
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
JslibModule,
|
||||
DialogModule,
|
||||
AsyncActionsModule,
|
||||
ButtonModule,
|
||||
ImportComponent,
|
||||
],
|
||||
})
|
||||
export class ImportDesktopComponent {
|
||||
protected disabled = false;
|
||||
protected loading = false;
|
||||
|
||||
constructor(public dialogRef: DialogRef) {}
|
||||
|
||||
/**
|
||||
* Callback that is called after a successful import.
|
||||
*/
|
||||
protected async onSuccessfulImport(organizationId: string): Promise<void> {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
@ -1662,6 +1662,9 @@
|
||||
"personalOwnershipPolicyInEffect": {
|
||||
"message": "An organization policy is affecting your ownership options."
|
||||
},
|
||||
"personalOwnershipPolicyInEffectImports": {
|
||||
"message": "An organization policy has blocked importing items into your individual vault."
|
||||
},
|
||||
"allSends": {
|
||||
"message": "All Sends",
|
||||
"description": "'Sends' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
@ -2427,5 +2430,113 @@
|
||||
},
|
||||
"aliasDomain": {
|
||||
"message": "Alias domain"
|
||||
},
|
||||
"importData": {
|
||||
"message": "Import data",
|
||||
"description": "Used for the desktop menu item and the header of the import dialog"
|
||||
},
|
||||
"importError": {
|
||||
"message": "Import error"
|
||||
},
|
||||
"importErrorDesc": {
|
||||
"message": "There was a problem with the data you tried to import. Please resolve the errors listed below in your source file and try again."
|
||||
},
|
||||
"resolveTheErrorsBelowAndTryAgain": {
|
||||
"message": "Resolve the errors below and try again."
|
||||
},
|
||||
"description": {
|
||||
"message": "Description"
|
||||
},
|
||||
"importSuccess": {
|
||||
"message": "Data successfully imported"
|
||||
},
|
||||
"importSuccessNumberOfItems": {
|
||||
"message": "A total of $AMOUNT$ items were imported.",
|
||||
"placeholders": {
|
||||
"amount": {
|
||||
"content": "$1",
|
||||
"example": "2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"total": {
|
||||
"message": "Total"
|
||||
},
|
||||
"importWarning": {
|
||||
"message": "You are importing data to $ORGANIZATION$. Your data may be shared with members of this organization. Do you want to proceed?",
|
||||
"placeholders": {
|
||||
"organization": {
|
||||
"content": "$1",
|
||||
"example": "My Org Name"
|
||||
}
|
||||
}
|
||||
},
|
||||
"importFormatError": {
|
||||
"message": "Data is not formatted correctly. Please check your import file and try again."
|
||||
},
|
||||
"importNothingError": {
|
||||
"message": "Nothing was imported."
|
||||
},
|
||||
"importEncKeyError": {
|
||||
"message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data."
|
||||
},
|
||||
"importDestination": {
|
||||
"message": "Import destination"
|
||||
},
|
||||
"learnAboutImportOptions": {
|
||||
"message": "Learn about your import options"
|
||||
},
|
||||
"selectImportFolder": {
|
||||
"message": "Select a folder"
|
||||
},
|
||||
"selectImportCollection": {
|
||||
"message": "Select a collection"
|
||||
},
|
||||
"importTargetHint": {
|
||||
"message": "Select this option if you want the imported file contents moved to a $DESTINATION$",
|
||||
"description": "Located as a hint under the import target. Will be appended by either folder or collection, depending if the user is importing into an individual or an organizational vault.",
|
||||
"placeholders": {
|
||||
"destination": {
|
||||
"content": "$1",
|
||||
"example": "folder or collection"
|
||||
}
|
||||
}
|
||||
},
|
||||
"importUnassignedItemsError": {
|
||||
"message": "File contains unassigned items."
|
||||
},
|
||||
"selectFormat": {
|
||||
"message": "Select the format of the import file"
|
||||
},
|
||||
"selectImportFile": {
|
||||
"message": "Select the import file"
|
||||
},
|
||||
"chooseFile": {
|
||||
"message": "Choose File"
|
||||
},
|
||||
"noFileChosen": {
|
||||
"message": "No file chosen"
|
||||
},
|
||||
"orCopyPasteFileContents": {
|
||||
"message": "or copy/paste the import file contents"
|
||||
},
|
||||
"instructionsFor": {
|
||||
"message": "$NAME$ Instructions",
|
||||
"description": "The title for the import tool instructions.",
|
||||
"placeholders": {
|
||||
"name": {
|
||||
"content": "$1",
|
||||
"example": "LastPass (csv)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"confirmVaultImport": {
|
||||
"message": "Confirm vault import"
|
||||
},
|
||||
"confirmVaultImportDesc": {
|
||||
"message": "This file is password-protected. Please enter the file password to import data."
|
||||
},
|
||||
"confirmFilePassword": {
|
||||
"message": "Confirm file password"
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ export class FileMenu extends FirstMenu implements IMenubarMenu {
|
||||
this.addNewFolder,
|
||||
this.separator,
|
||||
this.syncVault,
|
||||
this.importVault,
|
||||
this.exportVault,
|
||||
];
|
||||
|
||||
@ -123,6 +124,15 @@ export class FileMenu extends FirstMenu implements IMenubarMenu {
|
||||
};
|
||||
}
|
||||
|
||||
private get importVault(): MenuItemConstructorOptions {
|
||||
return {
|
||||
id: "importVault",
|
||||
label: this.localize("importData"),
|
||||
click: () => this.sendMessage("importVault"),
|
||||
enabled: !this._isLocked,
|
||||
};
|
||||
}
|
||||
|
||||
private get exportVault(): MenuItemConstructorOptions {
|
||||
return {
|
||||
id: "exportVault",
|
||||
|
Loading…
Reference in New Issue
Block a user