mirror of
https://github.com/bitwarden/browser
synced 2026-03-01 19:11:22 +00:00
[PM-31675] remove archive from web edit (#18764)
* refactor default cipher archive service, update archive/unarchive in vault-item-dialog, remove archive/unarchive items in edit form
This commit is contained in:
committed by
jaasen-livefront
parent
8e9a9c7e32
commit
d7cbfebfab
@@ -3,7 +3,7 @@
|
||||
{{ title }}
|
||||
</span>
|
||||
|
||||
@if (isCipherArchived && !params.isAdminConsoleAction) {
|
||||
@if (isCipherArchived && !params.isAdminConsoleAction && (archiveFlagEnabled$ | async)) {
|
||||
<span bitBadge bitDialogHeaderEnd> {{ "archived" | i18n }} </span>
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@
|
||||
|
||||
@if (showActionButtons) {
|
||||
<div class="tw-ml-auto">
|
||||
@if ((userCanArchive$ | async) && !params.isAdminConsoleAction) {
|
||||
@if (isCipherArchived && !cipher?.isDeleted) {
|
||||
@if (showArchiveOptions) {
|
||||
@if (showUnarchiveBtn) {
|
||||
<button
|
||||
type="button"
|
||||
class="tw-mr-1"
|
||||
@@ -96,7 +96,7 @@
|
||||
[label]="'unArchive' | i18n"
|
||||
></button>
|
||||
}
|
||||
@if (cipher?.canBeArchived) {
|
||||
@if (showArchiveBtn) {
|
||||
<button
|
||||
type="button"
|
||||
class="tw-mr-1"
|
||||
|
||||
@@ -119,7 +119,7 @@ describe("VaultItemDialogComponent", () => {
|
||||
provide: CipherArchiveService,
|
||||
useValue: {
|
||||
userCanArchive$: jest.fn().mockReturnValue(of(true)),
|
||||
hasArchiveFlagEnabled$: jest.fn().mockReturnValue(of(true)),
|
||||
hasArchiveFlagEnabled$: of(true),
|
||||
archiveWithServer: jest.fn().mockResolvedValue({}),
|
||||
unarchiveWithServer: jest.fn().mockResolvedValue({}),
|
||||
},
|
||||
@@ -258,19 +258,19 @@ describe("VaultItemDialogComponent", () => {
|
||||
expect(archiveButton).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should show archive button when the user can archive the item and the item can be archived", () => {
|
||||
it("should show archive button when the user can archive the item, item can be archived, and dialog is in view mode", () => {
|
||||
component.setTestCipher({ canBeArchived: true });
|
||||
(component as any).userCanArchive$ = of(true);
|
||||
component.setTestParams({ mode: "form" });
|
||||
component.setTestParams({ mode: "view" });
|
||||
fixture.detectChanges();
|
||||
const archiveButton = fixture.debugElement.query(By.css("[biticonbutton='bwi-archive']"));
|
||||
expect(archiveButton).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should not show archive button when the user cannot archive the item", () => {
|
||||
it("should not show archive button when the user does not have premium", () => {
|
||||
(component as any).userCanArchive$ = of(false);
|
||||
component.setTestCipher({});
|
||||
component.setTestParams({ mode: "form" });
|
||||
component.setTestParams({ mode: "view" });
|
||||
fixture.detectChanges();
|
||||
const archiveButton = fixture.debugElement.query(By.css("[biticonbutton='bwi-archive']"));
|
||||
expect(archiveButton).toBeFalsy();
|
||||
@@ -283,18 +283,35 @@ describe("VaultItemDialogComponent", () => {
|
||||
const archiveButton = fixture.debugElement.query(By.css("[biticonbutton='bwi-archive']"));
|
||||
expect(archiveButton).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should not show archive button when dialog is not in view mode", () => {
|
||||
component.setTestCipher({ canBeArchived: true });
|
||||
(component as any).userCanArchive$ = of(true);
|
||||
component.setTestParams({ mode: "form" });
|
||||
fixture.detectChanges();
|
||||
const archiveButton = fixture.debugElement.query(By.css("[biticonbutton='bwi-archive']"));
|
||||
expect(archiveButton).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("unarchive button", () => {
|
||||
it("should show the unarchive button when the item is archived", () => {
|
||||
it("should show the unarchive button when the item is archived, and dialog in view mode", () => {
|
||||
component.setTestCipher({ isArchived: true });
|
||||
component.setTestParams({ mode: "form" });
|
||||
component.setTestParams({ mode: "view" });
|
||||
fixture.detectChanges();
|
||||
const unarchiveButton = fixture.debugElement.query(By.css("[biticonbutton='bwi-unarchive']"));
|
||||
expect(unarchiveButton).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should not show the unarchive button when the item is not archived", () => {
|
||||
component.setTestCipher({ isArchived: false });
|
||||
component.setTestParams({ mode: "view" });
|
||||
fixture.detectChanges();
|
||||
const unarchiveButton = fixture.debugElement.query(By.css("[biticonbutton='bwi-unarchive']"));
|
||||
expect(unarchiveButton).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should not show the unarchive button when dialog is not in view mode", () => {
|
||||
component.setTestCipher({ isArchived: false });
|
||||
component.setTestParams({ mode: "form" });
|
||||
fixture.detectChanges();
|
||||
|
||||
@@ -28,7 +28,7 @@ import { EventType } from "@bitwarden/common/enums";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { CipherId, CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherArchiveService } from "@bitwarden/common/vault/abstractions/cipher-archive.service";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
|
||||
@@ -293,6 +293,20 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
return this.cipher?.isArchived;
|
||||
}
|
||||
|
||||
private _userCanArchive = false;
|
||||
|
||||
protected get showArchiveOptions(): boolean {
|
||||
return this._userCanArchive && !this.params.isAdminConsoleAction && this.params.mode === "view";
|
||||
}
|
||||
|
||||
protected get showArchiveBtn(): boolean {
|
||||
return this.cipher?.canBeArchived;
|
||||
}
|
||||
|
||||
protected get showUnarchiveBtn(): boolean {
|
||||
return this.isCipherArchived && !this.cipher?.isDeleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to initialize/attach the form component.
|
||||
*/
|
||||
@@ -341,6 +355,8 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
takeUntilDestroyed(),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
this.userCanArchive$.pipe(takeUntilDestroyed()).subscribe((v) => (this._userCanArchive = v));
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
@@ -574,20 +590,14 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
await this.changeMode("view");
|
||||
};
|
||||
|
||||
updateCipherFromArchive = (revisionDate: Date, archivedDate: Date | null) => {
|
||||
this.cipher.archivedDate = archivedDate;
|
||||
this.cipher.revisionDate = revisionDate;
|
||||
updateCipherFromResponse = async (cipherResponse: CipherData, userId: UserId) => {
|
||||
const cipher: Cipher = new Cipher(cipherResponse);
|
||||
|
||||
// If we're in View mode, we don't need to update the form.
|
||||
if (this.params.mode === "view") {
|
||||
return;
|
||||
}
|
||||
cipher.collectionIds = [...this.cipher.collectionIds];
|
||||
|
||||
this.cipherFormComponent().patchCipher((current) => {
|
||||
current.revisionDate = revisionDate;
|
||||
current.archivedDate = archivedDate;
|
||||
return current;
|
||||
});
|
||||
const cipherView = await this.cipherService.decrypt(cipher, userId);
|
||||
|
||||
await this.onCipherSaved(cipherView);
|
||||
};
|
||||
|
||||
archive = async () => {
|
||||
@@ -597,10 +607,8 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
this.cipher.id as CipherId,
|
||||
activeUserId,
|
||||
);
|
||||
this.updateCipherFromArchive(
|
||||
new Date(cipherResponse.revisionDate),
|
||||
cipherResponse.archivedDate ? new Date(cipherResponse.archivedDate) : null,
|
||||
);
|
||||
|
||||
await this.updateCipherFromResponse(cipherResponse, activeUserId);
|
||||
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
@@ -621,7 +629,9 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
this.cipher.id as CipherId,
|
||||
activeUserId,
|
||||
);
|
||||
this.updateCipherFromArchive(new Date(cipherResponse.revisionDate), null);
|
||||
|
||||
await this.updateCipherFromResponse(cipherResponse, activeUserId);
|
||||
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
message: this.i18nService.t("itemWasUnarchived"),
|
||||
@@ -631,7 +641,6 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
|
||||
variant: "error",
|
||||
message: this.i18nService.t("errorOccurred"),
|
||||
});
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user