mirror of https://github.com/bitwarden/web.git
Browse Source
* [fix] Pull org admin vault collections directly from the API
* [refactor] Establish pattern for interfaces in module scoped services
* [fix] Remove access modifiers from constructor params for an extended service
* [fix] Rename skipFilterCollectionRefresh to firstLoaded
* [fix] Simplify hiding unwanted filters in the org vault
* Revert "[refactor] Establish pattern for interfaces in module scoped services"
This reverts commit f1edae5a3e.
* Update src/app/modules/vault-filter/vault-filter.component.ts
Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
* Update src/app/modules/vault-filter/organization-vault-filter.component.ts
Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
* [fix] Ran prettier
Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
pull/1727/head
8 changed files with 111 additions and 57 deletions
@ -1 +1 @@ |
|||||||
Subproject commit 2b647df001f6bdfbeb6f272a0b7b56396ac9564d |
Subproject commit f4066b4f58af2e6e4ce82275b72a2a8501f25e78 |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
import { Component, Input } from "@angular/core"; |
||||||
|
|
||||||
|
import { Organization } from "jslib-common/models/domain/organization"; |
||||||
|
|
||||||
|
import { VaultFilterComponent } from "./vault-filter.component"; |
||||||
|
|
||||||
|
@Component({ |
||||||
|
selector: "app-organization-vault-filter", |
||||||
|
templateUrl: "vault-filter.component.html", |
||||||
|
}) |
||||||
|
export class OrganizationVaultFilterComponent extends VaultFilterComponent { |
||||||
|
hideOrganizations = true; |
||||||
|
hideFavorites = true; |
||||||
|
hideFolders = true; |
||||||
|
|
||||||
|
organization: Organization; |
||||||
|
|
||||||
|
async initCollections() { |
||||||
|
if (this.organization.canEditAnyCollection) { |
||||||
|
return await this.vaultFilterService.buildAdminCollections(this.organization.id); |
||||||
|
} |
||||||
|
return await this.vaultFilterService.buildCollections(this.organization.id); |
||||||
|
} |
||||||
|
|
||||||
|
async reloadCollectionsAndFolders() { |
||||||
|
this.collections = await this.initCollections(); |
||||||
|
} |
||||||
|
} |
||||||
@ -1,34 +1,26 @@ |
|||||||
import { Component, EventEmitter, Input, Output } from "@angular/core"; |
import { Component, EventEmitter, Output } from "@angular/core"; |
||||||
|
|
||||||
import { VaultFilterComponent as BaseVaultFilterComponent } from "jslib-angular/modules/vault-filter/vault-filter.component"; |
import { VaultFilterComponent as BaseVaultFilterComponent } from "jslib-angular/modules/vault-filter/vault-filter.component"; |
||||||
import { VaultFilterService } from "jslib-angular/modules/vault-filter/vault-filter.service"; |
|
||||||
import { Organization } from "jslib-common/models/domain/organization"; |
import { VaultFilterService } from "./vault-filter.service"; |
||||||
|
|
||||||
@Component({ |
@Component({ |
||||||
selector: "app-vault-filter", |
selector: "app-vault-filter", |
||||||
templateUrl: "vault-filter.component.html", |
templateUrl: "vault-filter.component.html", |
||||||
}) |
}) |
||||||
export class VaultFilterComponent extends BaseVaultFilterComponent { |
export class VaultFilterComponent extends BaseVaultFilterComponent { |
||||||
@Input() showOrgFilter = true; |
|
||||||
@Input() showFolders = true; |
|
||||||
@Input() showFavorites = true; |
|
||||||
|
|
||||||
@Output() onSearchTextChanged = new EventEmitter<string>(); |
@Output() onSearchTextChanged = new EventEmitter<string>(); |
||||||
|
|
||||||
searchPlaceholder: string; |
searchPlaceholder: string; |
||||||
searchText = ""; |
searchText = ""; |
||||||
|
|
||||||
organization: Organization; |
constructor(protected vaultFilterService: VaultFilterService) { |
||||||
|
// This empty constructor is required to provide the web vaultFilterService subclass to super()
|
||||||
constructor(vaultFilterService: VaultFilterService) { |
// TODO: refactor this to use proper dependency injection
|
||||||
super(vaultFilterService); |
super(vaultFilterService); |
||||||
} |
} |
||||||
|
|
||||||
searchTextChanged() { |
searchTextChanged() { |
||||||
this.onSearchTextChanged.emit(this.searchText); |
this.onSearchTextChanged.emit(this.searchText); |
||||||
} |
} |
||||||
|
|
||||||
async initCollections() { |
|
||||||
return await this.vaultFilterService.buildCollections(this.organization?.id); |
|
||||||
} |
|
||||||
} |
} |
||||||
|
|||||||
@ -1,3 +1,54 @@ |
|||||||
|
import { Injectable } from "@angular/core"; |
||||||
|
|
||||||
|
import { DynamicTreeNode } from "jslib-angular/modules/vault-filter/models/dynamic-tree-node.model"; |
||||||
import { VaultFilterService as BaseVaultFilterService } from "jslib-angular/modules/vault-filter/vault-filter.service"; |
import { VaultFilterService as BaseVaultFilterService } from "jslib-angular/modules/vault-filter/vault-filter.service"; |
||||||
|
import { ApiService } from "jslib-common/abstractions/api.service"; |
||||||
|
import { CipherService } from "jslib-common/abstractions/cipher.service"; |
||||||
|
import { CollectionService } from "jslib-common/abstractions/collection.service"; |
||||||
|
import { FolderService } from "jslib-common/abstractions/folder.service"; |
||||||
|
import { OrganizationService } from "jslib-common/abstractions/organization.service"; |
||||||
|
import { PolicyService } from "jslib-common/abstractions/policy.service"; |
||||||
|
import { StateService } from "jslib-common/abstractions/state.service"; |
||||||
|
import { CollectionData } from "jslib-common/models/data/collectionData"; |
||||||
|
import { Collection } from "jslib-common/models/domain/collection"; |
||||||
|
import { CollectionDetailsResponse } from "jslib-common/models/response/collectionResponse"; |
||||||
|
import { CollectionView } from "jslib-common/models/view/collectionView"; |
||||||
|
|
||||||
|
@Injectable() |
||||||
|
export class VaultFilterService extends BaseVaultFilterService { |
||||||
|
constructor( |
||||||
|
stateService: StateService, |
||||||
|
organizationService: OrganizationService, |
||||||
|
folderService: FolderService, |
||||||
|
cipherService: CipherService, |
||||||
|
collectionService: CollectionService, |
||||||
|
policyService: PolicyService, |
||||||
|
protected apiService: ApiService |
||||||
|
) { |
||||||
|
super( |
||||||
|
stateService, |
||||||
|
organizationService, |
||||||
|
folderService, |
||||||
|
cipherService, |
||||||
|
collectionService, |
||||||
|
policyService |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async buildAdminCollections(organizationId: string) { |
||||||
|
let result: CollectionView[] = []; |
||||||
|
const collectionResponse = await this.apiService.getCollections(organizationId); |
||||||
|
if (collectionResponse?.data != null && collectionResponse.data.length) { |
||||||
|
const collectionDomains = collectionResponse.data.map( |
||||||
|
(r: CollectionDetailsResponse) => new Collection(new CollectionData(r)) |
||||||
|
); |
||||||
|
result = await this.collectionService.decryptMany(collectionDomains); |
||||||
|
} |
||||||
|
|
||||||
export class VaultFilterService extends BaseVaultFilterService {} |
const nestedCollections = await this.collectionService.getAllNested(result); |
||||||
|
return new DynamicTreeNode<CollectionView>({ |
||||||
|
fullList: result, |
||||||
|
nestedList: nestedCollections, |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|||||||
Loading…
Reference in new issue