mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
initial integration of combined dialog
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { TestBed } from "@angular/core/testing";
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
import { CollectionAdminService } from "@bitwarden/admin-console/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
@@ -9,7 +10,6 @@ import { CipherId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
|
||||
|
||||
import { CollectionAdminService } from "../../core/collection-admin.service";
|
||||
import { RoutedVaultFilterService } from "../../individual-vault/vault-filter/services/routed-vault-filter.service";
|
||||
|
||||
import { AdminConsoleCipherFormConfigService } from "./admin-console-cipher-form-config.service";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { inject, Injectable } from "@angular/core";
|
||||
import { combineLatest, defer, filter, firstValueFrom, map, switchMap } from "rxjs";
|
||||
|
||||
import { CollectionAdminService } from "@bitwarden/admin-console/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
@@ -18,7 +19,6 @@ import {
|
||||
CipherFormConfigService,
|
||||
CipherFormMode,
|
||||
} from "../../../../../../../libs/vault/src/cipher-form/abstractions/cipher-form-config.service";
|
||||
import { CollectionAdminService } from "../../core/collection-admin.service";
|
||||
import { RoutedVaultFilterService } from "../../individual-vault/vault-filter/services/routed-vault-filter.service";
|
||||
|
||||
/** Admin Console implementation of the `CipherFormConfigService`. */
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DialogRef } from "@angular/cdk/dialog";
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
@@ -64,6 +65,7 @@ import { CollectionView } from "@bitwarden/common/vault/models/view/collection.v
|
||||
import { ServiceUtils } from "@bitwarden/common/vault/service-utils";
|
||||
import { DialogService, Icons, NoItemsModule, ToastService } from "@bitwarden/components";
|
||||
import {
|
||||
CipherFormConfig,
|
||||
CipherFormConfigService,
|
||||
CollectionAssignmentResult,
|
||||
PasswordRepromptService,
|
||||
@@ -80,6 +82,11 @@ import {
|
||||
CollectionDialogTabType,
|
||||
openCollectionDialog,
|
||||
} from "../components/collection-dialog";
|
||||
import {
|
||||
VaultItemDialogComponent,
|
||||
VaultItemDialogMode,
|
||||
VaultItemDialogResult,
|
||||
} from "../components/vault-item-dialog/vault-item-dialog.component";
|
||||
import { VaultItemEvent } from "../components/vault-items/vault-item-event";
|
||||
import { VaultItemsModule } from "../components/vault-items/vault-items.module";
|
||||
import {
|
||||
@@ -184,6 +191,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
private destroy$ = new Subject<void>();
|
||||
protected addAccessStatus$ = new BehaviorSubject<AddAccessStatusType>(0);
|
||||
private extensionRefreshEnabled: boolean;
|
||||
private vaultItemDialogRef?: DialogRef<VaultItemDialogResult> | undefined;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
@@ -481,6 +489,8 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
firstSetup$
|
||||
.pipe(
|
||||
switchMap(() => this.route.queryParams),
|
||||
// Only process the queryParams if the dialog is not open (only when extension refresh is enabled)
|
||||
filter(() => this.vaultItemDialogRef == undefined || !this.extensionRefreshEnabled),
|
||||
withLatestFrom(allCipherMap$, allCollections$, organization$),
|
||||
switchMap(async ([qParams, allCiphersMap]) => {
|
||||
const cipherId = getCipherIdFromParams(qParams);
|
||||
@@ -490,10 +500,15 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
const cipher = allCiphersMap[cipherId];
|
||||
|
||||
if (cipher) {
|
||||
if (qParams.action === "view") {
|
||||
// Only allow for edit in the admin console via query params,
|
||||
// This prevents multiple modals from stacking on top of each other between view & edit.
|
||||
// TODO: PM-12398 - combine view/edit actions into a single dialog
|
||||
let action = qParams.action;
|
||||
// Default to "view" if extension refresh is enabled
|
||||
if (action == null && this.extensionRefreshEnabled) {
|
||||
action = "view";
|
||||
}
|
||||
|
||||
if (action === "view") {
|
||||
await this.viewCipherById(cipherId);
|
||||
} else {
|
||||
await this.editCipherId(cipherId, false);
|
||||
}
|
||||
} else {
|
||||
@@ -877,18 +892,52 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
cipherId,
|
||||
);
|
||||
|
||||
const dialogRef = openAddEditCipherDialog(this.dialogService, {
|
||||
data: cipherFormConfig,
|
||||
await this.openVaultItemDialog("form", cipherFormConfig);
|
||||
}
|
||||
|
||||
/** Opens the view dialog for the given cipher unless password reprompt fails */
|
||||
async viewCipherById(id: string) {
|
||||
const cipher = await this.cipherService.get(id);
|
||||
// If cipher exists (cipher is null when new) and MP reprompt
|
||||
// is on for this cipher, then show password reprompt.
|
||||
if (
|
||||
cipher &&
|
||||
cipher.reprompt !== 0 &&
|
||||
!(await this.passwordRepromptService.showPasswordPrompt())
|
||||
) {
|
||||
// Didn't pass password prompt, so don't open add / edit modal.
|
||||
await this.go({ cipherId: null, itemId: null, action: null });
|
||||
return;
|
||||
}
|
||||
|
||||
const cipherFormConfig = await this.cipherFormConfigService.buildConfig(
|
||||
cipher?.edit ? "edit" : "partial-edit",
|
||||
id as CipherId,
|
||||
cipher?.type,
|
||||
);
|
||||
|
||||
await this.openVaultItemDialog("view", cipherFormConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the combined view / edit dialog for a cipher.
|
||||
*/
|
||||
async openVaultItemDialog(mode: VaultItemDialogMode, formConfig: CipherFormConfig) {
|
||||
this.vaultItemDialogRef = VaultItemDialogComponent.open(this.dialogService, {
|
||||
mode,
|
||||
formConfig,
|
||||
});
|
||||
|
||||
const result: AddEditCipherDialogCloseResult = await firstValueFrom(dialogRef.closed);
|
||||
const result = await lastValueFrom(this.vaultItemDialogRef.closed);
|
||||
this.vaultItemDialogRef = undefined;
|
||||
|
||||
// When the cipher was edited, refresh the vault view
|
||||
if (result?.action === AddEditCipherDialogResult.Edited) {
|
||||
// If the dialog was closed by deleting the cipher, refresh the vault.
|
||||
if (result === VaultItemDialogResult.Deleted || result === VaultItemDialogResult.Saved) {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
this.go({ cipherId: null, itemId: null, action: null });
|
||||
// Clear the query params when the dialog closes
|
||||
await this.go({ cipherId: null, itemId: null, action: null });
|
||||
}
|
||||
|
||||
async cloneCipher(cipher: CipherView) {
|
||||
|
||||
Reference in New Issue
Block a user