mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 06:13:38 +00:00
[PM-14952] - remove Edit button and show restore button when viewing item in trash (#12847)
* add restore function to vault item dialog * update comment * revert removing of delete button * use canDeleteCipher$ * put canRestore in class property * set showRestore after canDeleteCipher is set
This commit is contained in:
@@ -36,7 +36,10 @@
|
|||||||
</vault-cipher-form>
|
</vault-cipher-form>
|
||||||
</div>
|
</div>
|
||||||
<ng-container bitDialogFooter>
|
<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
|
<button
|
||||||
bitButton
|
bitButton
|
||||||
[bitAction]="switchToEdit"
|
[bitAction]="switchToEdit"
|
||||||
@@ -53,7 +56,7 @@
|
|||||||
form="cipherForm"
|
form="cipherForm"
|
||||||
buttonType="primary"
|
buttonType="primary"
|
||||||
#submitBtn
|
#submitBtn
|
||||||
[hidden]="showCipherView"
|
[hidden]="showCipherView || showRestore"
|
||||||
>
|
>
|
||||||
{{ "save" | i18n }}
|
{{ "save" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
@@ -62,7 +65,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
buttonType="secondary"
|
buttonType="secondary"
|
||||||
(click)="cancel()"
|
(click)="cancel()"
|
||||||
*ngIf="!showCipherView"
|
*ngIf="!showCipherView && !showRestore"
|
||||||
>
|
>
|
||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ import {
|
|||||||
AttachmentDialogResult,
|
AttachmentDialogResult,
|
||||||
AttachmentsV2Component,
|
AttachmentsV2Component,
|
||||||
} from "../../individual-vault/attachments-v2.component";
|
} 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 { WebCipherFormGenerationService } from "../../services/web-cipher-form-generation.service";
|
||||||
import { WebVaultPremiumUpgradePromptService } from "../../services/web-premium-upgrade-prompt.service";
|
import { WebVaultPremiumUpgradePromptService } from "../../services/web-premium-upgrade-prompt.service";
|
||||||
import { WebViewPasswordHistoryService } from "../../services/web-view-password-history.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.
|
* If true, the dialog is being opened from the admin console.
|
||||||
*/
|
*/
|
||||||
isAdminConsoleAction?: boolean;
|
isAdminConsoleAction?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to restore a cipher from the trash.
|
||||||
|
*/
|
||||||
|
restore: (c: CipherView) => Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum VaultItemDialogResult {
|
export enum VaultItemDialogResult {
|
||||||
@@ -99,6 +106,11 @@ export enum VaultItemDialogResult {
|
|||||||
* The dialog was closed to navigate the user the premium upgrade page.
|
* The dialog was closed to navigate the user the premium upgrade page.
|
||||||
*/
|
*/
|
||||||
PremiumUpgrade = "premiumUpgrade",
|
PremiumUpgrade = "premiumUpgrade",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cipher was restored
|
||||||
|
*/
|
||||||
|
Restored = "restored",
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -121,6 +133,7 @@ export enum VaultItemDialogResult {
|
|||||||
{ provide: PremiumUpgradePromptService, useClass: WebVaultPremiumUpgradePromptService },
|
{ provide: PremiumUpgradePromptService, useClass: WebVaultPremiumUpgradePromptService },
|
||||||
{ provide: ViewPasswordHistoryService, useClass: WebViewPasswordHistoryService },
|
{ provide: ViewPasswordHistoryService, useClass: WebViewPasswordHistoryService },
|
||||||
{ provide: CipherFormGenerationService, useClass: WebCipherFormGenerationService },
|
{ provide: CipherFormGenerationService, useClass: WebCipherFormGenerationService },
|
||||||
|
RoutedVaultFilterService,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||||
@@ -191,6 +204,20 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the user may restore the item.
|
||||||
|
* A user may restore items if they have delete permissions and the item is in the trash.
|
||||||
|
*/
|
||||||
|
protected async canUserRestore() {
|
||||||
|
return (
|
||||||
|
this.filter?.type === "trash" &&
|
||||||
|
this.cipher?.isDeleted &&
|
||||||
|
(await firstValueFrom(this.canDeleteCipher$))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected showRestore: boolean;
|
||||||
|
|
||||||
protected get loadingForm() {
|
protected get loadingForm() {
|
||||||
return this.loadForm && !this.formReady;
|
return this.loadForm && !this.formReady;
|
||||||
}
|
}
|
||||||
@@ -230,6 +257,8 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
protected canDeleteCipher$: Observable<boolean>;
|
protected canDeleteCipher$: Observable<boolean>;
|
||||||
|
|
||||||
|
protected filter: RoutedVaultFilterModel;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DIALOG_DATA) protected params: VaultItemDialogParams,
|
@Inject(DIALOG_DATA) protected params: VaultItemDialogParams,
|
||||||
private dialogRef: DialogRef<VaultItemDialogResult>,
|
private dialogRef: DialogRef<VaultItemDialogResult>,
|
||||||
@@ -246,6 +275,7 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
|||||||
private cipherAuthorizationService: CipherAuthorizationService,
|
private cipherAuthorizationService: CipherAuthorizationService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private eventCollectionService: EventCollectionService,
|
private eventCollectionService: EventCollectionService,
|
||||||
|
private routedVaultFilterService: RoutedVaultFilterService,
|
||||||
) {
|
) {
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
}
|
||||||
@@ -283,6 +313,9 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.filter = await firstValueFrom(this.routedVaultFilterService.filter$);
|
||||||
|
|
||||||
|
this.showRestore = await this.canUserRestore();
|
||||||
this.performingInitialLoad = false;
|
this.performingInitialLoad = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,6 +369,11 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
|||||||
this._formReadySubject.next();
|
this._formReadySubject.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restore = async () => {
|
||||||
|
await this.params.restore(this.cipher);
|
||||||
|
this.dialogRef.close(VaultItemDialogResult.Restored);
|
||||||
|
};
|
||||||
|
|
||||||
delete = async () => {
|
delete = async () => {
|
||||||
if (!this.cipher) {
|
if (!this.cipher) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -717,6 +717,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
mode,
|
mode,
|
||||||
formConfig,
|
formConfig,
|
||||||
activeCollectionId,
|
activeCollectionId,
|
||||||
|
restore: this.restore,
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = await lastValueFrom(this.vaultItemDialogRef.closed);
|
const result = await lastValueFrom(this.vaultItemDialogRef.closed);
|
||||||
|
|||||||
@@ -994,6 +994,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
disableForm,
|
disableForm,
|
||||||
activeCollectionId,
|
activeCollectionId,
|
||||||
isAdminConsoleAction: true,
|
isAdminConsoleAction: true,
|
||||||
|
restore: this.restore,
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = await lastValueFrom(this.vaultItemDialogRef.closed);
|
const result = await lastValueFrom(this.vaultItemDialogRef.closed);
|
||||||
@@ -1033,7 +1034,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async restore(c: CipherView): Promise<boolean> {
|
restore = async (c: CipherView): Promise<boolean> => {
|
||||||
if (!c.isDeleted) {
|
if (!c.isDeleted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1064,7 +1065,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logService.error(e);
|
this.logService.error(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
async bulkRestore(ciphers: CipherView[]) {
|
async bulkRestore(ciphers: CipherView[]) {
|
||||||
if (
|
if (
|
||||||
|
|||||||
Reference in New Issue
Block a user