import { Component, EventEmitter, OnInit, Output } from "@angular/core"; import { CipherService } from "@bitwarden/common/abstractions/cipher.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/abstractions/log.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction"; import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { CipherType } from "@bitwarden/common/enums/cipherType"; import { Utils } from "@bitwarden/common/misc/utils"; import { CipherView } from "@bitwarden/common/models/view/cipher.view"; import { Verification } from "@bitwarden/common/types/verification"; import { WebI18nKey } from "../../core/web-i18n.service.implementation"; class CountBasedLocalizationKey { singular: WebI18nKey; plural: WebI18nKey; getKey(count: number) { return count == 1 ? this.singular : this.plural; } constructor(singular: WebI18nKey, plural: WebI18nKey) { this.singular = singular; this.plural = plural; } } class OrganizationContentSummaryItem { count: number; get localizationKey() { return this.localizationKeyOptions.getKey(this.count); } private localizationKeyOptions: CountBasedLocalizationKey; constructor(count: number, localizationKeyOptions: CountBasedLocalizationKey) { this.count = count; this.localizationKeyOptions = localizationKeyOptions; } } class OrganizationContentSummary { totalItemCount = 0; itemCountByType: OrganizationContentSummaryItem[] = []; } @Component({ selector: "app-delete-organization", templateUrl: "delete-organization.component.html", }) export class DeleteOrganizationComponent implements OnInit { organizationId: string; loaded: boolean; deleteOrganizationRequestType: "InvalidFamiliesForEnterprise" | "RegularDelete" = "RegularDelete"; organizationName: string; organizationContentSummary: OrganizationContentSummary = new OrganizationContentSummary(); @Output() onSuccess: EventEmitter = new EventEmitter(); masterPassword: Verification; formPromise: Promise; constructor( private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, private userVerificationService: UserVerificationService, private logService: LogService, private cipherService: CipherService, private organizationService: OrganizationService, private organizationApiService: OrganizationApiServiceAbstraction ) {} async ngOnInit(): Promise { await this.load(); } async submit() { try { this.formPromise = this.userVerificationService .buildRequest(this.masterPassword) .then((request) => this.organizationApiService.delete(this.organizationId, request)); await this.formPromise; this.platformUtilsService.showToast( "success", this.i18nService.t("organizationDeleted"), this.i18nService.t("organizationDeletedDesc") ); this.onSuccess.emit(); } catch (e) { this.logService.error(e); } } private async load() { this.organizationName = (await this.organizationService.get(this.organizationId)).name; this.organizationContentSummary = await this.buildOrganizationContentSummary(); this.loaded = true; } private async buildOrganizationContentSummary(): Promise { const organizationContentSummary = new OrganizationContentSummary(); const organizationItems = ( await this.cipherService.getAllFromApiForOrganization(this.organizationId) ).filter((item) => item.deletedDate == null); if (organizationItems.length < 1) { return organizationContentSummary; } organizationContentSummary.totalItemCount = organizationItems.length; for (const cipherType of Utils.iterateEnum(CipherType)) { const count = this.getOrganizationItemCountByType(organizationItems, cipherType); if (count > 0) { organizationContentSummary.itemCountByType.push( new OrganizationContentSummaryItem( count, this.getOrganizationItemLocalizationKeysByType(CipherType[cipherType]) ) ); } } return organizationContentSummary; } private getOrganizationItemCountByType(items: CipherView[], type: CipherType) { return items.filter((item) => item.type == type).length; } private getOrganizationItemLocalizationKeysByType(type: string): CountBasedLocalizationKey { return new CountBasedLocalizationKey( `type${type}` as WebI18nKey, `type${type}Plural` as WebI18nKey ); } }