mirror of
https://github.com/bitwarden/browser
synced 2026-02-11 05:53:42 +00:00
add restore function to vault item dialog
This commit is contained in:
@@ -36,7 +36,10 @@
|
||||
</vault-cipher-form>
|
||||
</div>
|
||||
<ng-container bitDialogFooter>
|
||||
<ng-container *ngIf="showCipherView">
|
||||
<button *ngIf="showRestore" [bitAction]="restore" bitButton buttonType="primary" type="button">
|
||||
{{ "restore" | i18n }}
|
||||
</button>
|
||||
<ng-container *ngIf="showCipherView && !showRestore">
|
||||
<button
|
||||
bitButton
|
||||
[bitAction]="switchToEdit"
|
||||
@@ -53,7 +56,7 @@
|
||||
form="cipherForm"
|
||||
buttonType="primary"
|
||||
#submitBtn
|
||||
[hidden]="showCipherView"
|
||||
[hidden]="showCipherView || showRestore"
|
||||
>
|
||||
{{ "save" | i18n }}
|
||||
</button>
|
||||
@@ -62,11 +65,11 @@
|
||||
type="button"
|
||||
buttonType="secondary"
|
||||
(click)="cancel()"
|
||||
*ngIf="!showCipherView"
|
||||
*ngIf="!showCipherView && !showRestore"
|
||||
>
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
<div class="tw-ml-auto" *ngIf="showDelete">
|
||||
<div class="tw-ml-auto" *ngIf="showDelete && !showRestore">
|
||||
<button
|
||||
bitIconButton="bwi-trash"
|
||||
type="button"
|
||||
|
||||
@@ -49,6 +49,8 @@ import {
|
||||
AttachmentDialogResult,
|
||||
AttachmentsV2Component,
|
||||
} from "../../individual-vault/attachments-v2.component";
|
||||
import { RoutedVaultFilterService } from "../../individual-vault/vault-filter/services/routed-vault-filter.service";
|
||||
import { RoutedVaultFilterModel } from "../../individual-vault/vault-filter/shared/models/routed-vault-filter.model";
|
||||
import { WebCipherFormGenerationService } from "../../services/web-cipher-form-generation.service";
|
||||
import { WebVaultPremiumUpgradePromptService } from "../../services/web-premium-upgrade-prompt.service";
|
||||
import { WebViewPasswordHistoryService } from "../../services/web-view-password-history.service";
|
||||
@@ -82,6 +84,11 @@ export interface VaultItemDialogParams {
|
||||
* If true, the dialog is being opened from the admin console.
|
||||
*/
|
||||
isAdminConsoleAction?: boolean;
|
||||
|
||||
/**
|
||||
* Function to restore a cipher from the trash.
|
||||
*/
|
||||
restore: (c: CipherView) => Promise<boolean>;
|
||||
}
|
||||
|
||||
export enum VaultItemDialogResult {
|
||||
@@ -99,6 +106,11 @@ export enum VaultItemDialogResult {
|
||||
* The dialog was closed to navigate the user the premium upgrade page.
|
||||
*/
|
||||
PremiumUpgrade = "premiumUpgrade",
|
||||
|
||||
/**
|
||||
* A cipher was restored
|
||||
*/
|
||||
Restored = "restored",
|
||||
}
|
||||
|
||||
@Component({
|
||||
@@ -121,6 +133,7 @@ export enum VaultItemDialogResult {
|
||||
{ provide: PremiumUpgradePromptService, useClass: WebVaultPremiumUpgradePromptService },
|
||||
{ provide: ViewPasswordHistoryService, useClass: WebViewPasswordHistoryService },
|
||||
{ provide: CipherFormGenerationService, useClass: WebCipherFormGenerationService },
|
||||
RoutedVaultFilterService,
|
||||
],
|
||||
})
|
||||
export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
@@ -216,6 +229,40 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
return this.cipher != undefined && (this.params.mode === "view" || this.loadingForm);
|
||||
}
|
||||
|
||||
protected get showRestore() {
|
||||
return this.filter?.type === "trash" && this.canRestoreCipher && !!this.params.restore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user can restore the given cipher from the trash
|
||||
* Rules for when a cipher can be restored:
|
||||
* - the cipher is deleted
|
||||
* - AND
|
||||
* - the cipher is a personal item (doesn't belong to an organization)
|
||||
* - the cipher belongs to a collection that the user can manage
|
||||
* - the user is an admin of the organization
|
||||
*/
|
||||
protected get canRestoreCipher() {
|
||||
if (!this.cipher || !this.cipher.isDeleted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.cipher.organizationId == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const collection = this.collections.find((c) => this.cipher.collectionIds.includes(c.id));
|
||||
if (collection?.manage) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.organization?.isAdmin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to initialize/attach the form component.
|
||||
*/
|
||||
@@ -230,6 +277,8 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
|
||||
protected canDeleteCipher$: Observable<boolean>;
|
||||
|
||||
protected filter: RoutedVaultFilterModel;
|
||||
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) protected params: VaultItemDialogParams,
|
||||
private dialogRef: DialogRef<VaultItemDialogResult>,
|
||||
@@ -246,6 +295,7 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
private cipherAuthorizationService: CipherAuthorizationService,
|
||||
private apiService: ApiService,
|
||||
private eventCollectionService: EventCollectionService,
|
||||
private routedVaultFilterService: RoutedVaultFilterService,
|
||||
) {
|
||||
this.updateTitle();
|
||||
}
|
||||
@@ -283,6 +333,8 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
this.filter = await firstValueFrom(this.routedVaultFilterService.filter$);
|
||||
|
||||
this.performingInitialLoad = false;
|
||||
}
|
||||
|
||||
@@ -336,6 +388,11 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
this._formReadySubject.next();
|
||||
}
|
||||
|
||||
restore = async () => {
|
||||
await this.params.restore(this.cipher);
|
||||
this.dialogRef.close(VaultItemDialogResult.Restored);
|
||||
};
|
||||
|
||||
delete = async () => {
|
||||
if (!this.cipher) {
|
||||
return;
|
||||
|
||||
@@ -717,6 +717,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
mode,
|
||||
formConfig,
|
||||
activeCollectionId,
|
||||
restore: this.restore,
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(this.vaultItemDialogRef.closed);
|
||||
|
||||
@@ -988,6 +988,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
disableForm,
|
||||
activeCollectionId,
|
||||
isAdminConsoleAction: true,
|
||||
restore: this.restore,
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(this.vaultItemDialogRef.closed);
|
||||
@@ -1027,7 +1028,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
async restore(c: CipherView): Promise<boolean> {
|
||||
restore = async (c: CipherView): Promise<boolean> => {
|
||||
if (!c.isDeleted) {
|
||||
return;
|
||||
}
|
||||
@@ -1058,7 +1059,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async bulkRestore(ciphers: CipherView[]) {
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user