[PM-1992] in ac add current collection actions in menu and deprecate collections component (#11364)

* Removing feature flag

* Removing flag from feature-flag.enum.ts

* suggested changes

* prettier

* fixing merge conflict issue

* Removing unused code

* suggested change from Gbubemi

* Adding back merge conflict code

* fixing prettier styling

* Deprecating collections component, removing unused code now that we dont use collections component in AC

* Removing all Collections component logic from loos-components module and removing the files themselves as they are no longer needed.
This commit is contained in:
cd-bitwarden 2024-10-25 14:19:56 -04:00 committed by GitHub
parent 85194fd1b5
commit 8b64f0de9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 0 additions and 298 deletions

View File

@ -76,13 +76,11 @@ import { PremiumBadgeComponent } from "../vault/components/premium-badge.compone
import { AddEditCustomFieldsComponent } from "../vault/individual-vault/add-edit-custom-fields.component"; import { AddEditCustomFieldsComponent } from "../vault/individual-vault/add-edit-custom-fields.component";
import { AddEditComponent } from "../vault/individual-vault/add-edit.component"; import { AddEditComponent } from "../vault/individual-vault/add-edit.component";
import { AttachmentsComponent } from "../vault/individual-vault/attachments.component"; import { AttachmentsComponent } from "../vault/individual-vault/attachments.component";
import { CollectionsComponent } from "../vault/individual-vault/collections.component";
import { FolderAddEditComponent } from "../vault/individual-vault/folder-add-edit.component"; import { FolderAddEditComponent } from "../vault/individual-vault/folder-add-edit.component";
import { OrganizationBadgeModule } from "../vault/individual-vault/organization-badge/organization-badge.module"; import { OrganizationBadgeModule } from "../vault/individual-vault/organization-badge/organization-badge.module";
import { PipesModule } from "../vault/individual-vault/pipes/pipes.module"; import { PipesModule } from "../vault/individual-vault/pipes/pipes.module";
import { AddEditComponent as OrgAddEditComponent } from "../vault/org-vault/add-edit.component"; import { AddEditComponent as OrgAddEditComponent } from "../vault/org-vault/add-edit.component";
import { AttachmentsComponent as OrgAttachmentsComponent } from "../vault/org-vault/attachments.component"; import { AttachmentsComponent as OrgAttachmentsComponent } from "../vault/org-vault/attachments.component";
import { CollectionsComponent as OrgCollectionsComponent } from "../vault/org-vault/collections.component";
import { PurgeVaultComponent } from "../vault/settings/purge-vault.component"; import { PurgeVaultComponent } from "../vault/settings/purge-vault.component";
import { EnvironmentSelectorModule } from "./../components/environment-selector/environment-selector.module"; import { EnvironmentSelectorModule } from "./../components/environment-selector/environment-selector.module";
@ -123,7 +121,6 @@ import { SharedModule } from "./shared.module";
ApiKeyComponent, ApiKeyComponent,
AttachmentsComponent, AttachmentsComponent,
ChangeEmailComponent, ChangeEmailComponent,
CollectionsComponent,
DeauthorizeSessionsComponent, DeauthorizeSessionsComponent,
DeleteAccountDialogComponent, DeleteAccountDialogComponent,
DomainRulesComponent, DomainRulesComponent,
@ -139,7 +136,6 @@ import { SharedModule } from "./shared.module";
HintComponent, HintComponent,
OrgAddEditComponent, OrgAddEditComponent,
OrgAttachmentsComponent, OrgAttachmentsComponent,
OrgCollectionsComponent,
OrgEventsComponent, OrgEventsComponent,
OrgExposedPasswordsReportComponent, OrgExposedPasswordsReportComponent,
OrgInactiveTwoFactorReportComponent, OrgInactiveTwoFactorReportComponent,
@ -192,7 +188,6 @@ import { SharedModule } from "./shared.module";
ApiKeyComponent, ApiKeyComponent,
AttachmentsComponent, AttachmentsComponent,
ChangeEmailComponent, ChangeEmailComponent,
CollectionsComponent,
DeauthorizeSessionsComponent, DeauthorizeSessionsComponent,
DeleteAccountDialogComponent, DeleteAccountDialogComponent,
DomainRulesComponent, DomainRulesComponent,
@ -210,7 +205,6 @@ import { SharedModule } from "./shared.module";
OrgAddEditComponent, OrgAddEditComponent,
OrganizationLayoutComponent, OrganizationLayoutComponent,
OrgAttachmentsComponent, OrgAttachmentsComponent,
OrgCollectionsComponent,
OrgEventsComponent, OrgEventsComponent,
OrgExposedPasswordsReportComponent, OrgExposedPasswordsReportComponent,
OrgInactiveTwoFactorReportComponent, OrgInactiveTwoFactorReportComponent,

View File

@ -1,52 +0,0 @@
<form (ngSubmit)="submit()">
<bit-dialog>
<span bitDialogTitle>
{{ "collections" | i18n }}
<small *ngIf="cipher">{{ cipher.name }}</small>
</span>
<ng-container bitDialogContent>
<p>{{ "collectionsDesc" | i18n }}</p>
<div class="tw-flex">
<label class="tw-mb-1 tw-block tw-font-semibold tw-text-main">{{
"collections" | i18n
}}</label>
<div class="tw-ml-auto tw-flex" *ngIf="collections && collections.length">
<button bitLink type="button" (click)="selectAll(true)" class="tw-px-2">
{{ "selectAll" | i18n }}
</button>
<button bitLink type="button" (click)="selectAll(false)" class="tw-px-2">
{{ "unselectAll" | i18n }}
</button>
</div>
</div>
<div *ngIf="!collections || !collections.length">
{{ "noCollectionsInList" | i18n }}
</div>
<bit-table *ngIf="collections && collections.length">
<ng-template body>
<tr bitRow *ngFor="let c of collections; let i = index" (click)="check(c)">
<td bitCell>
<input
type="checkbox"
bitCheckbox
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
appStopProp
[disabled]="!c.canEditItems(this.organization)"
/>
{{ c.name }}
</td>
</tr>
</ng-template>
</bit-table>
</ng-container>
<ng-container bitDialogFooter>
<button bitButton buttonType="primary" type="submit">
{{ "save" | i18n }}
</button>
<button bitButton bitDialogClose buttonType="secondary" type="button">
{{ "cancel" | i18n }}
</button>
</ng-container>
</bit-dialog>
</form>

View File

@ -1,90 +0,0 @@
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
import { Component, Inject, OnDestroy } from "@angular/core";
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
import { CollectionsComponent as BaseCollectionsComponent } from "@bitwarden/angular/admin-console/components/collections.component";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { DialogService, ToastService } from "@bitwarden/components";
@Component({
selector: "app-vault-collections",
templateUrl: "collections.component.html",
})
export class CollectionsComponent extends BaseCollectionsComponent implements OnDestroy {
constructor(
collectionService: CollectionService,
platformUtilsService: PlatformUtilsService,
i18nService: I18nService,
cipherService: CipherService,
organizationSerivce: OrganizationService,
logService: LogService,
accountService: AccountService,
protected dialogRef: DialogRef,
@Inject(DIALOG_DATA) params: CollectionsDialogParams,
toastService: ToastService,
) {
super(
collectionService,
platformUtilsService,
i18nService,
cipherService,
organizationSerivce,
logService,
accountService,
toastService,
);
this.cipherId = params?.cipherId;
}
override async submit(): Promise<boolean> {
const success = await super.submit();
if (success) {
this.dialogRef.close(CollectionsDialogResult.Saved);
return true;
}
return false;
}
check(c: CollectionView, select?: boolean) {
if (!c.canEditItems(this.organization)) {
return;
}
(c as any).checked = select == null ? !(c as any).checked : select;
}
selectAll(select: boolean) {
this.collections.forEach((c) => this.check(c, select));
}
ngOnDestroy() {
this.selectAll(false);
}
}
export interface CollectionsDialogParams {
cipherId: string;
}
export enum CollectionsDialogResult {
Saved = "saved",
}
/**
* Strongly typed helper to open a Collections dialog
* @param dialogService Instance of the dialog service that will be used to open the dialog
* @param config Optional configuration for the dialog
*/
export function openIndividualVaultCollectionsDialog(
dialogService: DialogService,
config?: DialogConfig<CollectionsDialogParams>,
) {
return dialogService.open<CollectionsDialogResult, CollectionsDialogParams>(
CollectionsComponent,
config,
);
}

View File

@ -1,115 +0,0 @@
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
import { Component, Inject } from "@angular/core";
import { CollectionService, CollectionView } 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 { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CipherData } from "@bitwarden/common/vault/models/data/cipher.data";
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
import { CipherCollectionsRequest } from "@bitwarden/common/vault/models/request/cipher-collections.request";
import { DialogService, ToastService } from "@bitwarden/components";
import {
CollectionsComponent as BaseCollectionsComponent,
CollectionsDialogResult,
} from "../individual-vault/collections.component";
@Component({
selector: "app-org-vault-collections",
templateUrl: "../../vault/individual-vault/collections.component.html",
})
export class CollectionsComponent extends BaseCollectionsComponent {
organization: Organization;
constructor(
collectionService: CollectionService,
platformUtilsService: PlatformUtilsService,
i18nService: I18nService,
cipherService: CipherService,
organizationService: OrganizationService,
private apiService: ApiService,
logService: LogService,
accountService: AccountService,
protected dialogRef: DialogRef,
@Inject(DIALOG_DATA) params: OrgVaultCollectionsDialogParams,
toastService: ToastService,
) {
super(
collectionService,
platformUtilsService,
i18nService,
cipherService,
organizationService,
logService,
accountService,
dialogRef,
params,
toastService,
);
this.allowSelectNone = true;
this.collectionIds = params?.collectionIds;
this.collections = params?.collections;
this.organization = params?.organization;
this.cipherId = params?.cipherId;
}
protected async loadCipher() {
// if cipher is unassigned use apiService. We can see this by looking at this.collectionIds
if (!this.organization.canEditAllCiphers && this.collectionIds.length !== 0) {
return await super.loadCipher();
}
const response = await this.apiService.getCipherAdmin(this.cipherId);
return new Cipher(new CipherData(response));
}
protected loadCipherCollections() {
if (!this.organization.canViewAllCollections) {
return super.loadCipherCollections();
}
return this.collectionIds;
}
protected loadCollections() {
if (!this.organization.canViewAllCollections) {
return super.loadCollections();
}
return Promise.resolve(this.collections);
}
protected saveCollections() {
if (this.organization.canEditAllCiphers || this.collectionIds.length === 0) {
const request = new CipherCollectionsRequest(this.cipherDomain.collectionIds);
return this.apiService.putCipherCollectionsAdmin(this.cipherId, request);
} else {
return super.saveCollections();
}
}
}
export interface OrgVaultCollectionsDialogParams {
collectionIds: string[];
collections: CollectionView[];
organization: Organization;
cipherId: string;
}
/**
* Strongly typed helper to open a Collections dialog
* @param dialogService Instance of the dialog service that will be used to open the dialog
* @param config Optional configuration for the dialog
*/
export function openOrgVaultCollectionsDialog(
dialogService: DialogService,
config?: DialogConfig<OrgVaultCollectionsDialogParams>,
) {
return dialogService.open<CollectionsDialogResult, OrgVaultCollectionsDialogParams>(
CollectionsComponent,
config,
);
}

View File

@ -93,7 +93,6 @@ import {
BulkDeleteDialogResult, BulkDeleteDialogResult,
openBulkDeleteDialog, openBulkDeleteDialog,
} from "../individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component"; } from "../individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component";
import { CollectionsDialogResult } from "../individual-vault/collections.component";
import { RoutedVaultFilterBridgeService } from "../individual-vault/vault-filter/services/routed-vault-filter-bridge.service"; import { RoutedVaultFilterBridgeService } from "../individual-vault/vault-filter/services/routed-vault-filter-bridge.service";
import { RoutedVaultFilterService } from "../individual-vault/vault-filter/services/routed-vault-filter.service"; import { RoutedVaultFilterService } from "../individual-vault/vault-filter/services/routed-vault-filter.service";
import { createFilterFunction } from "../individual-vault/vault-filter/shared/models/filter-function"; import { createFilterFunction } from "../individual-vault/vault-filter/shared/models/filter-function";
@ -111,7 +110,6 @@ import {
BulkCollectionsDialogResult, BulkCollectionsDialogResult,
} from "./bulk-collections-dialog"; } from "./bulk-collections-dialog";
import { CollectionAccessRestrictedComponent } from "./collection-access-restricted.component"; import { CollectionAccessRestrictedComponent } from "./collection-access-restricted.component";
import { openOrgVaultCollectionsDialog } from "./collections.component";
import { AdminConsoleCipherFormConfigService } from "./services/admin-console-cipher-form-config.service"; import { AdminConsoleCipherFormConfigService } from "./services/admin-console-cipher-form-config.service";
import { VaultFilterModule } from "./vault-filter/vault-filter.module"; import { VaultFilterModule } from "./vault-filter/vault-filter.module";
const BroadcasterSubscriptionId = "OrgVaultComponent"; const BroadcasterSubscriptionId = "OrgVaultComponent";
@ -718,39 +716,6 @@ export class VaultComponent implements OnInit, OnDestroy {
}); });
} }
async editCipherCollections(cipher: CipherView) {
let collections: CollectionAdminView[] = [];
// Admins limited to only adding items to collections they have access to.
collections = await firstValueFrom(
this.allCollectionsWithoutUnassigned$.pipe(
map((c) => {
return c.sort((a, b) => {
if (a.canEditItems(this.organization) && !b.canEditItems(this.organization)) {
return -1;
} else if (!a.canEditItems(this.organization) && b.canEditItems(this.organization)) {
return 1;
} else {
return a.name.localeCompare(b.name);
}
});
}),
),
);
const dialog = openOrgVaultCollectionsDialog(this.dialogService, {
data: {
collectionIds: cipher.collectionIds,
collections: collections,
organization: this.organization,
cipherId: cipher.id,
},
});
if ((await lastValueFrom(dialog.closed)) == CollectionsDialogResult.Saved) {
this.refresh();
}
}
async addCipher(cipherType?: CipherType) { async addCipher(cipherType?: CipherType) {
if (this.extensionRefreshEnabled) { if (this.extensionRefreshEnabled) {
return this.addCipherV2(cipherType); return this.addCipherV2(cipherType);