mirror of
https://github.com/bitwarden/browser.git
synced 2024-07-06 12:16:10 +02:00
[fix] Recreate web/1700 (#2863)
This is a 1:1 recreation of https://github.com/bitwarden/web/pulls/1700 for bitwarden/clients
This commit is contained in:
parent
351bfdede1
commit
8d87e32ea2
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,6 @@
|
||||||
appAutofocus
|
appAutofocus
|
||||||
/>
|
/>
|
||||||
<app-organization-filter
|
<app-organization-filter
|
||||||
*ngIf="showOrgFilter"
|
|
||||||
[hide]="hideOrganizations"
|
[hide]="hideOrganizations"
|
||||||
[activeFilter]="activeFilter"
|
[activeFilter]="activeFilter"
|
||||||
[collapsedFilterNodes]="collapsedFilterNodes"
|
[collapsedFilterNodes]="collapsedFilterNodes"
|
||||||
|
@ -39,7 +38,7 @@
|
||||||
></app-organization-filter>
|
></app-organization-filter>
|
||||||
<div class="filter">
|
<div class="filter">
|
||||||
<app-status-filter
|
<app-status-filter
|
||||||
[hideFavorites]="!showFavorites"
|
[hideFavorites]="hideFavorites"
|
||||||
[hideTrash]="hideTrash"
|
[hideTrash]="hideTrash"
|
||||||
[activeFilter]="activeFilter"
|
[activeFilter]="activeFilter"
|
||||||
(onFilterChange)="applyFilter($event)"
|
(onFilterChange)="applyFilter($event)"
|
||||||
|
@ -55,7 +54,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="filter">
|
<div class="filter">
|
||||||
<app-folder-filter
|
<app-folder-filter
|
||||||
[hide]="!showFolders"
|
[hide]="hideFolders"
|
||||||
[activeFilter]="activeFilter"
|
[activeFilter]="activeFilter"
|
||||||
[collapsedFilterNodes]="collapsedFilterNodes"
|
[collapsedFilterNodes]="collapsedFilterNodes"
|
||||||
[folderNodes]="folders"
|
[folderNodes]="folders"
|
||||||
|
|
|
@ -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,13 +1,5 @@
|
||||||
import { NgModule } from "@angular/core";
|
import { NgModule } from "@angular/core";
|
||||||
|
|
||||||
import { VaultFilterService } from "jslib-angular/modules/vault-filter/vault-filter.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 { SharedModule } from "../shared.module";
|
import { SharedModule } from "../shared.module";
|
||||||
|
|
||||||
import { CollectionFilterComponent } from "./components/collection-filter.component";
|
import { CollectionFilterComponent } from "./components/collection-filter.component";
|
||||||
|
@ -17,7 +9,9 @@ import { OrganizationFilterComponent } from "./components/organization-filter.co
|
||||||
import { OrganizationOptionsComponent } from "./components/organization-options.component";
|
import { OrganizationOptionsComponent } from "./components/organization-options.component";
|
||||||
import { StatusFilterComponent } from "./components/status-filter.component";
|
import { StatusFilterComponent } from "./components/status-filter.component";
|
||||||
import { TypeFilterComponent } from "./components/type-filter.component";
|
import { TypeFilterComponent } from "./components/type-filter.component";
|
||||||
|
import { OrganizationVaultFilterComponent } from "./organization-vault-filter.component";
|
||||||
import { VaultFilterComponent } from "./vault-filter.component";
|
import { VaultFilterComponent } from "./vault-filter.component";
|
||||||
|
import { VaultFilterService } from "./vault-filter.service";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [SharedModule],
|
imports: [SharedModule],
|
||||||
|
@ -29,22 +23,10 @@ import { VaultFilterComponent } from "./vault-filter.component";
|
||||||
OrganizationOptionsComponent,
|
OrganizationOptionsComponent,
|
||||||
StatusFilterComponent,
|
StatusFilterComponent,
|
||||||
TypeFilterComponent,
|
TypeFilterComponent,
|
||||||
|
OrganizationVaultFilterComponent,
|
||||||
LinkSsoComponent,
|
LinkSsoComponent,
|
||||||
],
|
],
|
||||||
exports: [VaultFilterComponent],
|
exports: [VaultFilterComponent, OrganizationVaultFilterComponent],
|
||||||
providers: [
|
providers: [VaultFilterService],
|
||||||
{
|
|
||||||
provide: VaultFilterService,
|
|
||||||
useClass: VaultFilterService,
|
|
||||||
deps: [
|
|
||||||
StateService,
|
|
||||||
OrganizationService,
|
|
||||||
FolderService,
|
|
||||||
CipherService,
|
|
||||||
CollectionService,
|
|
||||||
PolicyService,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class VaultFilterModule {}
|
export class VaultFilterModule {}
|
||||||
|
|
|
@ -1,3 +1,54 @@
|
||||||
import { VaultFilterService as BaseVaultFilterService } from "jslib-angular/modules/vault-filter/vault-filter.service";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
export class VaultFilterService extends BaseVaultFilterService {}
|
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 { 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
const nestedCollections = await this.collectionService.getAllNested(result);
|
||||||
|
return new DynamicTreeNode<CollectionView>({
|
||||||
|
fullList: result,
|
||||||
|
nestedList: nestedCollections,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,15 +4,12 @@
|
||||||
<div class="groupings">
|
<div class="groupings">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="inner-content">
|
<div class="inner-content">
|
||||||
<app-vault-filter
|
<app-organization-vault-filter
|
||||||
#vaultFilter
|
#vaultFilter
|
||||||
[showFolders]="false"
|
|
||||||
[showFavorites]="false"
|
|
||||||
[activeFilter]="activeFilter"
|
[activeFilter]="activeFilter"
|
||||||
[showOrgFilter]="false"
|
|
||||||
(onFilterChange)="applyVaultFilter($event)"
|
(onFilterChange)="applyVaultFilter($event)"
|
||||||
(onSearchTextChanged)="filterSearchText($event)"
|
(onSearchTextChanged)="filterSearchText($event)"
|
||||||
></app-vault-filter>
|
></app-organization-vault-filter>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,7 +29,7 @@ import { AddEditComponent } from "../../../../organizations/vault/add-edit.compo
|
||||||
import { AttachmentsComponent } from "../../../../organizations/vault/attachments.component";
|
import { AttachmentsComponent } from "../../../../organizations/vault/attachments.component";
|
||||||
import { CiphersComponent } from "../../../../organizations/vault/ciphers.component";
|
import { CiphersComponent } from "../../../../organizations/vault/ciphers.component";
|
||||||
import { CollectionsComponent } from "../../../../organizations/vault/collections.component";
|
import { CollectionsComponent } from "../../../../organizations/vault/collections.component";
|
||||||
import { VaultFilterComponent } from "../../../vault-filter/vault-filter.component";
|
import { OrganizationVaultFilterComponent } from "../../../vault-filter/organization-vault-filter.component";
|
||||||
import { VaultService } from "../../vault.service";
|
import { VaultService } from "../../vault.service";
|
||||||
|
|
||||||
const BroadcasterSubscriptionId = "OrgVaultComponent";
|
const BroadcasterSubscriptionId = "OrgVaultComponent";
|
||||||
|
@ -39,7 +39,8 @@ const BroadcasterSubscriptionId = "OrgVaultComponent";
|
||||||
templateUrl: "organization-vault.component.html",
|
templateUrl: "organization-vault.component.html",
|
||||||
})
|
})
|
||||||
export class OrganizationVaultComponent implements OnInit, OnDestroy {
|
export class OrganizationVaultComponent implements OnInit, OnDestroy {
|
||||||
@ViewChild("vaultFilter", { static: true }) vaultFilterComponent: VaultFilterComponent;
|
@ViewChild("vaultFilter", { static: true })
|
||||||
|
vaultFilterComponent: OrganizationVaultFilterComponent;
|
||||||
@ViewChild(CiphersComponent, { static: true }) ciphersComponent: CiphersComponent;
|
@ViewChild(CiphersComponent, { static: true }) ciphersComponent: CiphersComponent;
|
||||||
@ViewChild("attachments", { read: ViewContainerRef, static: true })
|
@ViewChild("attachments", { read: ViewContainerRef, static: true })
|
||||||
attachmentsModalRef: ViewContainerRef;
|
attachmentsModalRef: ViewContainerRef;
|
||||||
|
@ -57,6 +58,11 @@ export class OrganizationVaultComponent implements OnInit, OnDestroy {
|
||||||
trashCleanupWarning: string = null;
|
trashCleanupWarning: string = null;
|
||||||
activeFilter: VaultFilter = new VaultFilter();
|
activeFilter: VaultFilter = new VaultFilter();
|
||||||
|
|
||||||
|
// This is a hack to avoid redundant api calls that fetch OrganizationVaultFilterComponent collections
|
||||||
|
// When it makes sense to do so we should leverage some other communication method for change events that isn't directly tied to the query param for organizationId
|
||||||
|
// i.e. exposing the VaultFiltersService to the OrganizationSwitcherComponent to make relevant updates from a change event instead of just depending on the router
|
||||||
|
firstLoaded = true;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
|
@ -95,11 +101,7 @@ export class OrganizationVaultComponent implements OnInit, OnDestroy {
|
||||||
case "syncCompleted":
|
case "syncCompleted":
|
||||||
if (message.successfully) {
|
if (message.successfully) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.vaultFilterComponent.reloadCollectionsAndFolders(
|
this.vaultFilterComponent.reloadCollectionsAndFolders(),
|
||||||
new VaultFilter({
|
|
||||||
selectedOrganizationId: this.organization.id,
|
|
||||||
} as Partial<VaultFilter>)
|
|
||||||
),
|
|
||||||
this.ciphersComponent.refresh(),
|
this.ciphersComponent.refresh(),
|
||||||
]);
|
]);
|
||||||
this.changeDetectorRef.detectChanges();
|
this.changeDetectorRef.detectChanges();
|
||||||
|
@ -109,9 +111,12 @@ export class OrganizationVaultComponent implements OnInit, OnDestroy {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
await this.vaultFilterComponent.reloadCollectionsAndFolders(
|
|
||||||
new VaultFilter({ selectedOrganizationId: this.organization.id } as Partial<VaultFilter>)
|
if (this.firstLoaded) {
|
||||||
);
|
await this.vaultFilterComponent.reloadCollectionsAndFolders();
|
||||||
|
}
|
||||||
|
this.firstLoaded = true;
|
||||||
|
|
||||||
await this.ciphersComponent.reload();
|
await this.ciphersComponent.reload();
|
||||||
|
|
||||||
if (qParams.viewEvents != null) {
|
if (qParams.viewEvents != null) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user