1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 22:33:35 +00:00

[PM-9111] Extension: persist add/edit form (#12236)

* remove todo

* Retrieve cache cipher for add-edit form

* user prefilled cipher for add-edit form

* add listener for clearing view cache

* clear local cache when clearing global state

* track initial value of cache for down stream logic that should only occur on non-cached values

* add feature flag for edit form persistence

* add tests for cipher form cache service

* fix optional initialValues

* add services to cipher form storybook

* fix strict types

* rename variables to be platform agnostic

* use deconstructed collectionIds variable to avoid them be overwritten

* use the originalCipherView for initial values

* add comment about signal equality

* prevent events from being emitted when adding uris to the existing form

- This stops other values from being overwrote in the initialization process

* add check for cached cipher when adding initial uris
This commit is contained in:
Nick Krantz
2025-01-22 10:49:07 -06:00
committed by GitHub
parent 1dfae06856
commit 5c32e5020d
22 changed files with 460 additions and 139 deletions

View File

@@ -38,6 +38,7 @@ import {
import { CipherFormConfig } from "../abstractions/cipher-form-config.service";
import { CipherFormService } from "../abstractions/cipher-form.service";
import { CipherForm, CipherFormContainer } from "../cipher-form-container";
import { CipherFormCacheService } from "../services/default-cipher-form-cache.service";
import { AdditionalOptionsSectionComponent } from "./additional-options/additional-options-section.component";
import { CardDetailsSectionComponent } from "./card-details-section/card-details-section.component";
@@ -55,6 +56,9 @@ import { SshKeySectionComponent } from "./sshkey-section/sshkey-section.componen
provide: CipherFormContainer,
useExisting: forwardRef(() => CipherFormComponent),
},
{
provide: CipherFormCacheService,
},
],
imports: [
AsyncActionsModule,
@@ -164,6 +168,26 @@ export class CipherFormComponent implements AfterViewInit, OnInit, OnChanges, Ci
*/
patchCipher(updateFn: (current: CipherView) => CipherView): void {
this.updatedCipherView = updateFn(this.updatedCipherView);
// Cache the updated cipher
this.cipherFormCacheService.cacheCipherView(this.updatedCipherView);
}
/**
* Return initial values for given keys of a cipher
*/
getInitialCipherView(): CipherView {
const cachedCipherView = this.cipherFormCacheService.getCachedCipherView();
if (cachedCipherView) {
return cachedCipherView;
}
return this.originalCipherView;
}
/** */
initializedWithCachedCipher(): boolean {
return this.cipherFormCacheService.initializedWithValue;
}
/**
@@ -187,6 +211,8 @@ export class CipherFormComponent implements AfterViewInit, OnInit, OnChanges, Ci
// Force change detection so that all child components are destroyed and re-created
this.changeDetectorRef.detectChanges();
await this.cipherFormCacheService.init();
this.updatedCipherView = new CipherView();
this.originalCipherView = null;
this.cipherForm = this.formBuilder.group<CipherForm>({});
@@ -220,16 +246,39 @@ export class CipherFormComponent implements AfterViewInit, OnInit, OnChanges, Ci
}
}
this.setInitialCipherFromCache();
this.loading = false;
this.formReadySubject.next();
}
/**
* Updates `updatedCipherView` based on the value from the cache.
*/
setInitialCipherFromCache() {
const cachedCipher = this.cipherFormCacheService.getCachedCipherView();
if (cachedCipher === null) {
return;
}
// Use the cached cipher when it matches the cipher being edited
if (this.updatedCipherView.id === cachedCipher.id) {
this.updatedCipherView = cachedCipher;
}
// `id` is null when a cipher is being added
if (this.updatedCipherView.id === null) {
this.updatedCipherView = cachedCipher;
}
}
constructor(
private formBuilder: FormBuilder,
private addEditFormService: CipherFormService,
private toastService: ToastService,
private i18nService: I18nService,
private changeDetectorRef: ChangeDetectorRef,
private cipherFormCacheService: CipherFormCacheService,
) {}
/**