mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 05:13:29 +00:00
chore(view-cache): [PM-21154] Move view-cache its own feature package and adjust imports
* Moved view-cache services to directory * Fixed DI for browser extension. * Fixed tests.
This commit is contained in:
@@ -19,7 +19,7 @@ import {
|
|||||||
FormCacheOptions,
|
FormCacheOptions,
|
||||||
SignalCacheOptions,
|
SignalCacheOptions,
|
||||||
ViewCacheService,
|
ViewCacheService,
|
||||||
} from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
} from "@bitwarden/angular/platform/view-cache";
|
||||||
import { MessageSender } from "@bitwarden/common/platform/messaging";
|
import { MessageSender } from "@bitwarden/common/platform/messaging";
|
||||||
import { GlobalStateProvider } from "@bitwarden/common/platform/state";
|
import { GlobalStateProvider } from "@bitwarden/common/platform/state";
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import { Router } from "@angular/router";
|
|||||||
import { merge, of, Subject } from "rxjs";
|
import { merge, of, Subject } from "rxjs";
|
||||||
|
|
||||||
import { CollectionService } from "@bitwarden/admin-console/common";
|
import { CollectionService } from "@bitwarden/admin-console/common";
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
|
||||||
import { AngularThemingService } from "@bitwarden/angular/platform/services/theming/angular-theming.service";
|
import { AngularThemingService } from "@bitwarden/angular/platform/services/theming/angular-theming.service";
|
||||||
import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/safe-provider";
|
import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/safe-provider";
|
||||||
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import {
|
import {
|
||||||
CLIENT_TYPE,
|
CLIENT_TYPE,
|
||||||
DEFAULT_VAULT_TIMEOUT,
|
DEFAULT_VAULT_TIMEOUT,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { FormBuilder } from "@angular/forms";
|
|||||||
import { BehaviorSubject, skipWhile } from "rxjs";
|
import { BehaviorSubject, skipWhile } from "rxjs";
|
||||||
|
|
||||||
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
||||||
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
@@ -20,8 +21,6 @@ import { CipherType } from "@bitwarden/common/vault/enums";
|
|||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
||||||
|
|
||||||
import { PopupViewCacheService } from "../../../platform/popup/view-cache/popup-view-cache.service";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CachedFilterState,
|
CachedFilterState,
|
||||||
MY_VAULT_ID,
|
MY_VAULT_ID,
|
||||||
@@ -123,7 +122,7 @@ describe("VaultPopupListFiltersService", () => {
|
|||||||
useValue: accountService,
|
useValue: accountService,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: PopupViewCacheService,
|
provide: ViewCacheService,
|
||||||
useValue: viewCacheService,
|
useValue: viewCacheService,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
} from "rxjs";
|
} from "rxjs";
|
||||||
|
|
||||||
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
||||||
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model";
|
import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model";
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
@@ -40,8 +41,6 @@ import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
|||||||
import { ServiceUtils } from "@bitwarden/common/vault/service-utils";
|
import { ServiceUtils } from "@bitwarden/common/vault/service-utils";
|
||||||
import { ChipSelectOption } from "@bitwarden/components";
|
import { ChipSelectOption } from "@bitwarden/components";
|
||||||
|
|
||||||
import { PopupViewCacheService } from "../../../platform/popup/view-cache/popup-view-cache.service";
|
|
||||||
|
|
||||||
const FILTER_VISIBILITY_KEY = new KeyDefinition<boolean>(VAULT_SETTINGS_DISK, "filterVisibility", {
|
const FILTER_VISIBILITY_KEY = new KeyDefinition<boolean>(VAULT_SETTINGS_DISK, "filterVisibility", {
|
||||||
deserializer: (obj) => obj,
|
deserializer: (obj) => obj,
|
||||||
});
|
});
|
||||||
@@ -178,7 +177,7 @@ export class VaultPopupListFiltersService {
|
|||||||
private policyService: PolicyService,
|
private policyService: PolicyService,
|
||||||
private stateProvider: StateProvider,
|
private stateProvider: StateProvider,
|
||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
private viewCacheService: PopupViewCacheService,
|
private viewCacheService: ViewCacheService,
|
||||||
) {
|
) {
|
||||||
this.filterForm.controls.organization.valueChanges
|
this.filterForm.controls.organization.valueChanges
|
||||||
.pipe(takeUntilDestroyed())
|
.pipe(takeUntilDestroyed())
|
||||||
|
|||||||
1
libs/angular/src/platform/view-cache/index.ts
Normal file
1
libs/angular/src/platform/view-cache/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { ViewCacheService, FormCacheOptions, SignalCacheOptions } from "./view-cache.service";
|
||||||
1
libs/angular/src/platform/view-cache/internal.ts
Normal file
1
libs/angular/src/platform/view-cache/internal.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { NoopViewCacheService } from "./noop-view-cache.service";
|
||||||
@@ -1,11 +1,7 @@
|
|||||||
import { Injectable, signal, WritableSignal } from "@angular/core";
|
import { Injectable, signal, WritableSignal } from "@angular/core";
|
||||||
import type { FormGroup } from "@angular/forms";
|
import type { FormGroup } from "@angular/forms";
|
||||||
|
|
||||||
import {
|
import { FormCacheOptions, SignalCacheOptions, ViewCacheService } from "./view-cache.service";
|
||||||
FormCacheOptions,
|
|
||||||
SignalCacheOptions,
|
|
||||||
ViewCacheService,
|
|
||||||
} from "../abstractions/view-cache.service";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The functionality of the {@link ViewCacheService} is only needed in the browser extension popup,
|
* The functionality of the {@link ViewCacheService} is only needed in the browser extension popup,
|
||||||
130
libs/angular/src/platform/view-cache/view-cache.md
Normal file
130
libs/angular/src/platform/view-cache/view-cache.md
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
# Extension Persistence
|
||||||
|
|
||||||
|
By default, when the browser extension popup closes, the user's current view and any data entered
|
||||||
|
without saving is lost. This introduces friction in several workflows within our client, such as:
|
||||||
|
|
||||||
|
- Performing actions that require email OTP entry, since the user must navigate from the popup to
|
||||||
|
get to their email inbox
|
||||||
|
- Entering information to create a new vault item from a browser tab
|
||||||
|
- And many more
|
||||||
|
|
||||||
|
Previously, we have recommended that users "pop out" the extension into its own window to persist
|
||||||
|
the extension context, but this introduces additional user actions and may leave the extension open
|
||||||
|
(and unlocked) for longer than a user intends.
|
||||||
|
|
||||||
|
In order to provide a better user experience, we have introduced two levels of persistence to the
|
||||||
|
Bitwarden extension client:
|
||||||
|
|
||||||
|
- We persist the route history, allowing us to re-open the last route when the popup re-opens, and
|
||||||
|
- We offer a service for teams to use to persist component-specific form data or state to survive a
|
||||||
|
popup close/re-open cycle
|
||||||
|
|
||||||
|
## Persistence lifetime
|
||||||
|
|
||||||
|
Since we are persisting data, it is important that the lifetime of that data be well-understood and
|
||||||
|
well-constrained. The cache of route history and form data is cleared when any of the following
|
||||||
|
events occur:
|
||||||
|
|
||||||
|
- The account is locked
|
||||||
|
- The account is logged out
|
||||||
|
- Account switching is used to switch the active account
|
||||||
|
- The extension popup has been closed for 2 minutes
|
||||||
|
|
||||||
|
In addition, cached form data is cleared when a browser extension navigation event occurs (e.g.
|
||||||
|
switching between tabs in the extension).
|
||||||
|
|
||||||
|
## Types of persistence
|
||||||
|
|
||||||
|
### Route history persistence
|
||||||
|
|
||||||
|
Route history is persisted on the extension automatically, with no specific implementation required
|
||||||
|
on any component.
|
||||||
|
|
||||||
|
The persistence layer ensures that the popup will open at the same route as was active when it
|
||||||
|
closed, provided that none of the lifetime expiration events have occurred.
|
||||||
|
|
||||||
|
:::tip Excluding a route
|
||||||
|
|
||||||
|
If a particular route should be excluded from the history and not persisted, add
|
||||||
|
`doNotSaveUrl: true` to the `data` property on the route.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
### View data persistence
|
||||||
|
|
||||||
|
Route persistence ensures that the user will land back on the route that they were on when the popup
|
||||||
|
closed, but it does not persist any state or form data that the user may have modified. In order to
|
||||||
|
persist that data, the component is responsible for registering that data with the
|
||||||
|
[`ViewCacheService`](./view-cache.service.ts).
|
||||||
|
This is done prescriptively to ensure that only necessary data is cached and that it is done with
|
||||||
|
intention by the component.
|
||||||
|
|
||||||
|
The `ViewCacheService` provides an interface for caching both individual state and `FormGroup`s.
|
||||||
|
|
||||||
|
#### Caching individual data elements
|
||||||
|
|
||||||
|
For individual pieces of state, use the `signal()` method on the `ViewCacheService` to create a
|
||||||
|
writeable [signal](https://angular.dev/guide/signals) wrapper around the desired state.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const mySignal = this.viewCacheService.signal({
|
||||||
|
key: "my-state-key"
|
||||||
|
initialValue: null
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
If a cached value exists, the returned signal will contain the cached data.
|
||||||
|
|
||||||
|
Setting the value should be done through the signal's `set()` method:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const mySignal = this.viewCacheService.signal({
|
||||||
|
key: "my-state-key"
|
||||||
|
initialValue: null
|
||||||
|
});
|
||||||
|
mySignal.set("value")
|
||||||
|
```
|
||||||
|
|
||||||
|
:::note Equality comparison
|
||||||
|
|
||||||
|
By default, signals use `Object.is` to determine equality, and `set()` will only trigger updates if
|
||||||
|
the updated value is not equal to the current signal state. See documentation
|
||||||
|
[here](https://angular.dev/guide/signals#signal-equality-functions).
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
Putting this together, the most common implementation pattern would be:
|
||||||
|
|
||||||
|
1. **Register the signal** using `ViewCacheService.signal()` on initialization of the component or
|
||||||
|
service responsible for the state being persisted.
|
||||||
|
2. **Restore state from the signal:** If cached data exists, the signal will contain that data. The
|
||||||
|
component or service should use this data to re-create the state from prior to the popup closing.
|
||||||
|
3. **Set new state** in the cache when it changes. Ensure that any updates to the data are persisted
|
||||||
|
to the cache with `set()`, so that the cache reflects the latest state.
|
||||||
|
|
||||||
|
#### Caching form data
|
||||||
|
|
||||||
|
For persisting form data, the `ViewCacheService` supplies a `formGroup()` method, which manages the
|
||||||
|
persistence of any entered form data to the cache and the initialization of the form from the cached
|
||||||
|
data. You can supply the `FormGroup` in the `control` parameter of the method, and the
|
||||||
|
`ViewCacheService` will:
|
||||||
|
|
||||||
|
- Initialize the form the a cached value, if it exists
|
||||||
|
- Save form value to cache when it changes
|
||||||
|
- Mark the form dirty if the restored value is not `undefined`.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
this.loginDetailsForm = this.viewCacheService.formGroup({
|
||||||
|
key: "my-form",
|
||||||
|
control: this.formBuilder.group({
|
||||||
|
username: [""],
|
||||||
|
email: [""],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## What about other clients?
|
||||||
|
|
||||||
|
The `ViewCacheService` is designed to be injected into shared, client-agnostic components. A
|
||||||
|
`NoopViewCacheService` is provided and injected for non-extension clients, preserving a single
|
||||||
|
interface for your components.
|
||||||
@@ -42,6 +42,8 @@ export type FormCacheOptions<TFormGroup extends FormGroup> = BaseCacheOptions<
|
|||||||
/**
|
/**
|
||||||
* Cache for temporary component state
|
* Cache for temporary component state
|
||||||
*
|
*
|
||||||
|
* [Read more](./view-cache.md)
|
||||||
|
*
|
||||||
* #### Implementations
|
* #### Implementations
|
||||||
* - browser extension popup: used to persist UI between popup open and close
|
* - browser extension popup: used to persist UI between popup open and close
|
||||||
* - all other clients: noop
|
* - all other clients: noop
|
||||||
@@ -325,13 +325,14 @@ import {
|
|||||||
import { DeviceTrustToastService as DeviceTrustToastServiceAbstraction } from "../auth/services/device-trust-toast.service.abstraction";
|
import { DeviceTrustToastService as DeviceTrustToastServiceAbstraction } from "../auth/services/device-trust-toast.service.abstraction";
|
||||||
import { DeviceTrustToastService } from "../auth/services/device-trust-toast.service.implementation";
|
import { DeviceTrustToastService } from "../auth/services/device-trust-toast.service.implementation";
|
||||||
import { FormValidationErrorsService as FormValidationErrorsServiceAbstraction } from "../platform/abstractions/form-validation-errors.service";
|
import { FormValidationErrorsService as FormValidationErrorsServiceAbstraction } from "../platform/abstractions/form-validation-errors.service";
|
||||||
import { ViewCacheService } from "../platform/abstractions/view-cache.service";
|
|
||||||
import { FormValidationErrorsService } from "../platform/services/form-validation-errors.service";
|
import { FormValidationErrorsService } from "../platform/services/form-validation-errors.service";
|
||||||
import { LoggingErrorHandler } from "../platform/services/logging-error-handler";
|
import { LoggingErrorHandler } from "../platform/services/logging-error-handler";
|
||||||
import { NoopViewCacheService } from "../platform/services/noop-view-cache.service";
|
|
||||||
import { AngularThemingService } from "../platform/services/theming/angular-theming.service";
|
import { AngularThemingService } from "../platform/services/theming/angular-theming.service";
|
||||||
import { AbstractThemingService } from "../platform/services/theming/theming.service.abstraction";
|
import { AbstractThemingService } from "../platform/services/theming/theming.service.abstraction";
|
||||||
import { safeProvider, SafeProvider } from "../platform/utils/safe-provider";
|
import { safeProvider, SafeProvider } from "../platform/utils/safe-provider";
|
||||||
|
import { ViewCacheService } from "../platform/view-cache";
|
||||||
|
// eslint-disable-next-line no-restricted-imports -- Needed for DI
|
||||||
|
import { NoopViewCacheService } from "../platform/view-cache/internal";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CLIENT_TYPE,
|
CLIENT_TYPE,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { TestBed } from "@angular/core/testing";
|
|||||||
import { mock, MockProxy } from "jest-mock-extended";
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { TestBed } from "@angular/core/testing";
|
|||||||
import { mock, MockProxy } from "jest-mock-extended";
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { inject, Injectable, WritableSignal } from "@angular/core";
|
import { inject, Injectable, WritableSignal } from "@angular/core";
|
||||||
import { Jsonify } from "type-fest";
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { TestBed } from "@angular/core/testing";
|
|||||||
import { mock, MockProxy } from "jest-mock-extended";
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { inject, Injectable, WritableSignal } from "@angular/core";
|
import { inject, Injectable, WritableSignal } from "@angular/core";
|
||||||
import { Jsonify } from "type-fest";
|
import { Jsonify } from "type-fest";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { signal } from "@angular/core";
|
import { signal } from "@angular/core";
|
||||||
import { TestBed } from "@angular/core/testing";
|
import { TestBed } from "@angular/core/testing";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view";
|
import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { inject, Injectable, WritableSignal } from "@angular/core";
|
import { inject, Injectable, WritableSignal } from "@angular/core";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view";
|
import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import { CollectionView } from "@bitwarden/admin-console/common";
|
import { CollectionView } from "@bitwarden/admin-console/common";
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing";
|
|||||||
import { ReactiveFormsModule } from "@angular/forms";
|
import { ReactiveFormsModule } from "@angular/forms";
|
||||||
import { mock } from "jest-mock-extended";
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { signal } from "@angular/core";
|
import { signal } from "@angular/core";
|
||||||
import { TestBed } from "@angular/core/testing";
|
import { TestBed } from "@angular/core/testing";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { inject, Injectable } from "@angular/core";
|
import { inject, Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service";
|
import { ViewCacheService } from "@bitwarden/angular/platform/view-cache";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
|||||||
Reference in New Issue
Block a user