From ea97ffe60e41c8ca05367eca12f28712b16a62d8 Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Mon, 8 Aug 2022 15:27:56 -0700 Subject: [PATCH] [EC-8] Restructure Tabs (#3109) * Cherry pick pending PR for tabs component [CL-17] Tabs - Routing * Update organization tabs from 4 to 6 * Create initial 'Members' tab * Create initial 'Groups' tab * Add initial "Reporting" tab * Use correct report label/layout by product type * Create initial 'Billing' tab * Breakup billing payment and billing history pages * Cleanup org routing and nav permission service * More org tab permission cleanup * Refactor organization billing to use a module * Refactor organization reporting to use module * Cherry pick finished/merged tabs component [CL-17] Tabs - Router (#2952) * This partially reverts commit 24bb775 to fix tracking of people.component.html rename. * Fix people component file rename * Recover lost member page changes * Undo members component rename as it was causing difficult merge conflicts * Fix member and group page container * Remove unnecessary organization lookup * [EC-8] Some PR suggestions * [EC-8] Reuse user billing history for orgs * [EC-8] Renamed user billing history component * [EC-8] Repurpose payment method component Update end user payment method component to be usable for organizations. * [EC-8] Fix missing verify bank condition * [EC-8] Remove org payment method component * [EC-8] Use CL in payment method component * [EC-8] Extend maxWidth Tailwind theme config * [EC-8] Add lazy loading to org reports * [EC-8] Add lazy loading to org billing * [EC-8] Prettier * [EC-8] Cleanup org reporting component redundancy * [EC-8] Use different class for negative margin * [EC-8] Make billing history component "dumb" * Revert "[EC-8] Cleanup org reporting component redundancy" This reverts commit eca337e89bb0be4600af4351640636aa8a498cff. * [EC-8] Create and export shared reports module * [EC-8] Use shared reports module in orgs * [EC-8] Use takeUntil pattern * [EC-8] Move org reporting module out of old modules folder * [EC-8] Move org billing module out of old modules folder * [EC-8] Fix some remaining merge conflicts * [EC-8] Move maxWidth into 'extend' key for Tailwind config * [EC-8] Remove unused module * [EC-8] Rename org report list component * Prettier Co-authored-by: Vincent Salucci --- .../billing-sync-api-key.component.html | 0 .../billing-sync-api-key.component.ts | 0 ...zation-billing-history-view.component.html | 27 + ...nization-billing-history-view.component.ts | 35 ++ .../organization-billing-routing.module.ts | 47 ++ .../organization-billing-tab.component.html | 23 + .../organization-billing-tab.component.ts | 7 + .../billing/organization-billing.module.ts | 21 + .../organization-subscription.component.html | 0 .../organization-subscription.component.ts | 0 .../organization-layout.component.html | 45 +- .../layouts/organization-layout.component.ts | 56 +- .../manage/groups.component.html | 148 ++--- .../organizations/manage/groups.component.ts | 2 +- .../manage/people.component.html | 568 +++++++++--------- .../organizations/manage/people.component.ts | 2 +- .../organization-routing.module.ts | 187 +----- .../organization-reporting-routing.module.ts | 98 +++ .../organization-reporting.module.ts | 14 + .../reporting/reporting.component.html | 30 + .../reporting/reporting.component.ts | 24 + .../reporting/reports-home.component.html | 20 + .../reporting/reports-home.component.ts | 65 ++ .../navigation-permissions.service.ts | 34 +- .../settings/account.component.html | 27 +- .../settings/account.component.ts | 9 - .../organization-billing.component.html | 212 ------- .../organization-billing.component.ts | 154 ----- .../settings/settings.component.html | 13 +- apps/web/src/app/reports/index.ts | 4 +- .../reports/pages/reports-home.component.ts | 3 +- apps/web/src/app/reports/reports.module.ts | 7 +- apps/web/src/app/reports/reports.ts | 2 +- apps/web/src/app/reports/shared/index.ts | 3 + .../{ => shared}/models/report-entry.ts | 0 .../{ => shared}/models/report-variant.ts | 0 .../report-card/report-card.component.html | 2 +- .../report-card/report-card.component.ts | 0 .../report-card/report-card.stories.ts | 4 +- .../report-list/report-list.component.html | 0 .../report-list/report-list.component.ts | 0 .../report-list/report-list.stories.ts | 6 +- .../reports/shared/reports-shared.module.ts | 14 + .../billing-history-view.component.html | 27 + ...t.ts => billing-history-view.component.ts} | 25 +- .../settings/billing-history.component.html | 65 ++ .../app/settings/billing-history.component.ts | 41 ++ .../settings/payment-method.component.html | 85 ++- .../app/settings/payment-method.component.ts | 123 +++- .../settings/subscription-routing.module.ts | 4 +- .../user-billing-history.component.html | 98 --- .../src/app/shared/loose-components.module.ts | 17 +- apps/web/src/app/shared/shared.module.ts | 3 + apps/web/src/locales/en/messages.json | 13 + .../src/models/response/billingResponse.ts | 4 + libs/components/tailwind.config.base.js | 3 + 56 files changed, 1252 insertions(+), 1169 deletions(-) rename apps/web/src/app/organizations/{settings => billing}/billing-sync-api-key.component.html (100%) rename apps/web/src/app/organizations/{settings => billing}/billing-sync-api-key.component.ts (100%) create mode 100644 apps/web/src/app/organizations/billing/organization-billing-history-view.component.html create mode 100644 apps/web/src/app/organizations/billing/organization-billing-history-view.component.ts create mode 100644 apps/web/src/app/organizations/billing/organization-billing-routing.module.ts create mode 100644 apps/web/src/app/organizations/billing/organization-billing-tab.component.html create mode 100644 apps/web/src/app/organizations/billing/organization-billing-tab.component.ts create mode 100644 apps/web/src/app/organizations/billing/organization-billing.module.ts rename apps/web/src/app/organizations/{settings => billing}/organization-subscription.component.html (100%) rename apps/web/src/app/organizations/{settings => billing}/organization-subscription.component.ts (100%) create mode 100644 apps/web/src/app/organizations/reporting/organization-reporting-routing.module.ts create mode 100644 apps/web/src/app/organizations/reporting/organization-reporting.module.ts create mode 100644 apps/web/src/app/organizations/reporting/reporting.component.html create mode 100644 apps/web/src/app/organizations/reporting/reporting.component.ts create mode 100644 apps/web/src/app/organizations/reporting/reports-home.component.html create mode 100644 apps/web/src/app/organizations/reporting/reports-home.component.ts delete mode 100644 apps/web/src/app/organizations/settings/organization-billing.component.html delete mode 100644 apps/web/src/app/organizations/settings/organization-billing.component.ts create mode 100644 apps/web/src/app/reports/shared/index.ts rename apps/web/src/app/reports/{ => shared}/models/report-entry.ts (100%) rename apps/web/src/app/reports/{ => shared}/models/report-variant.ts (100%) rename apps/web/src/app/reports/{ => shared}/report-card/report-card.component.html (74%) rename apps/web/src/app/reports/{ => shared}/report-card/report-card.component.ts (100%) rename apps/web/src/app/reports/{ => shared}/report-card/report-card.stories.ts (88%) rename apps/web/src/app/reports/{ => shared}/report-list/report-list.component.html (100%) rename apps/web/src/app/reports/{ => shared}/report-list/report-list.component.ts (100%) rename apps/web/src/app/reports/{ => shared}/report-list/report-list.stories.ts (84%) create mode 100644 apps/web/src/app/reports/shared/reports-shared.module.ts create mode 100644 apps/web/src/app/settings/billing-history-view.component.html rename apps/web/src/app/settings/{user-billing-history.component.ts => billing-history-view.component.ts} (53%) create mode 100644 apps/web/src/app/settings/billing-history.component.html create mode 100644 apps/web/src/app/settings/billing-history.component.ts delete mode 100644 apps/web/src/app/settings/user-billing-history.component.html diff --git a/apps/web/src/app/organizations/settings/billing-sync-api-key.component.html b/apps/web/src/app/organizations/billing/billing-sync-api-key.component.html similarity index 100% rename from apps/web/src/app/organizations/settings/billing-sync-api-key.component.html rename to apps/web/src/app/organizations/billing/billing-sync-api-key.component.html diff --git a/apps/web/src/app/organizations/settings/billing-sync-api-key.component.ts b/apps/web/src/app/organizations/billing/billing-sync-api-key.component.ts similarity index 100% rename from apps/web/src/app/organizations/settings/billing-sync-api-key.component.ts rename to apps/web/src/app/organizations/billing/billing-sync-api-key.component.ts diff --git a/apps/web/src/app/organizations/billing/organization-billing-history-view.component.html b/apps/web/src/app/organizations/billing/organization-billing-history-view.component.html new file mode 100644 index 00000000000..6622245ad1d --- /dev/null +++ b/apps/web/src/app/organizations/billing/organization-billing-history-view.component.html @@ -0,0 +1,27 @@ + + + + {{ "loading" | i18n }} + + + + diff --git a/apps/web/src/app/organizations/billing/organization-billing-history-view.component.ts b/apps/web/src/app/organizations/billing/organization-billing-history-view.component.ts new file mode 100644 index 00000000000..6680b3f19a9 --- /dev/null +++ b/apps/web/src/app/organizations/billing/organization-billing-history-view.component.ts @@ -0,0 +1,35 @@ +import { Component, OnInit } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; + +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { BillingHistoryResponse } from "@bitwarden/common/models/response/billingHistoryResponse"; + +@Component({ + selector: "app-org-billing-history-view", + templateUrl: "organization-billing-history-view.component.html", +}) +export class OrgBillingHistoryViewComponent implements OnInit { + loading = false; + firstLoaded = false; + billing: BillingHistoryResponse; + organizationId: string; + + constructor(private apiService: ApiService, private route: ActivatedRoute) {} + + async ngOnInit() { + this.route.params.subscribe(async (params) => { + this.organizationId = params.organizationId; + await this.load(); + this.firstLoaded = true; + }); + } + + async load() { + if (this.loading) { + return; + } + this.loading = true; + this.billing = await this.apiService.getOrganizationBilling(this.organizationId); + this.loading = false; + } +} diff --git a/apps/web/src/app/organizations/billing/organization-billing-routing.module.ts b/apps/web/src/app/organizations/billing/organization-billing-routing.module.ts new file mode 100644 index 00000000000..476b98e1c36 --- /dev/null +++ b/apps/web/src/app/organizations/billing/organization-billing-routing.module.ts @@ -0,0 +1,47 @@ +import { NgModule } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; + +import { Permissions } from "@bitwarden/common/enums/permissions"; + +import { PaymentMethodComponent } from "../../settings/payment-method.component"; +import { PermissionsGuard } from "../guards/permissions.guard"; +import { NavigationPermissionsService } from "../services/navigation-permissions.service"; + +import { OrgBillingHistoryViewComponent } from "./organization-billing-history-view.component"; +import { OrganizationBillingTabComponent } from "./organization-billing-tab.component"; +import { OrganizationSubscriptionComponent } from "./organization-subscription.component"; + +const routes: Routes = [ + { + path: "", + component: OrganizationBillingTabComponent, + canActivate: [PermissionsGuard], + data: { permissions: NavigationPermissionsService.getPermissions("billing") }, + children: [ + { path: "", pathMatch: "full", redirectTo: "subscription" }, + { + path: "subscription", + component: OrganizationSubscriptionComponent, + data: { titleId: "subscription" }, + }, + { + path: "payment-method", + component: PaymentMethodComponent, + canActivate: [PermissionsGuard], + data: { titleId: "paymentMethod", permissions: [Permissions.ManageBilling] }, + }, + { + path: "history", + component: OrgBillingHistoryViewComponent, + canActivate: [PermissionsGuard], + data: { titleId: "billingHistory", permissions: [Permissions.ManageBilling] }, + }, + ], + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class OrganizationBillingRoutingModule {} diff --git a/apps/web/src/app/organizations/billing/organization-billing-tab.component.html b/apps/web/src/app/organizations/billing/organization-billing-tab.component.html new file mode 100644 index 00000000000..b01c0eea7f0 --- /dev/null +++ b/apps/web/src/app/organizations/billing/organization-billing-tab.component.html @@ -0,0 +1,23 @@ + diff --git a/apps/web/src/app/organizations/billing/organization-billing-tab.component.ts b/apps/web/src/app/organizations/billing/organization-billing-tab.component.ts new file mode 100644 index 00000000000..17f47e54d10 --- /dev/null +++ b/apps/web/src/app/organizations/billing/organization-billing-tab.component.ts @@ -0,0 +1,7 @@ +import { Component } from "@angular/core"; + +@Component({ + selector: "app-org-billing-tab", + templateUrl: "organization-billing-tab.component.html", +}) +export class OrganizationBillingTabComponent {} diff --git a/apps/web/src/app/organizations/billing/organization-billing.module.ts b/apps/web/src/app/organizations/billing/organization-billing.module.ts new file mode 100644 index 00000000000..7e2dcf534e9 --- /dev/null +++ b/apps/web/src/app/organizations/billing/organization-billing.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from "@angular/core"; + +import { LooseComponentsModule } from "../../shared/loose-components.module"; +import { SharedModule } from "../../shared/shared.module"; + +import { BillingSyncApiKeyComponent } from "./billing-sync-api-key.component"; +import { OrgBillingHistoryViewComponent } from "./organization-billing-history-view.component"; +import { OrganizationBillingRoutingModule } from "./organization-billing-routing.module"; +import { OrganizationBillingTabComponent } from "./organization-billing-tab.component"; +import { OrganizationSubscriptionComponent } from "./organization-subscription.component"; + +@NgModule({ + imports: [SharedModule, LooseComponentsModule, OrganizationBillingRoutingModule], + declarations: [ + BillingSyncApiKeyComponent, + OrganizationBillingTabComponent, + OrganizationSubscriptionComponent, + OrgBillingHistoryViewComponent, + ], +}) +export class OrganizationBillingModule {} diff --git a/apps/web/src/app/organizations/settings/organization-subscription.component.html b/apps/web/src/app/organizations/billing/organization-subscription.component.html similarity index 100% rename from apps/web/src/app/organizations/settings/organization-subscription.component.html rename to apps/web/src/app/organizations/billing/organization-subscription.component.html diff --git a/apps/web/src/app/organizations/settings/organization-subscription.component.ts b/apps/web/src/app/organizations/billing/organization-subscription.component.ts similarity index 100% rename from apps/web/src/app/organizations/settings/organization-subscription.component.ts rename to apps/web/src/app/organizations/billing/organization-subscription.component.ts diff --git a/apps/web/src/app/organizations/layouts/organization-layout.component.html b/apps/web/src/app/organizations/layouts/organization-layout.component.html index 3834635e189..8716e12740d 100644 --- a/apps/web/src/app/organizations/layouts/organization-layout.component.html +++ b/apps/web/src/app/organizations/layouts/organization-layout.component.html @@ -6,34 +6,27 @@ class="my-auto pl-1" [activeOrganization]="organization" > - + + {{ "vault" | i18n }} + {{ + "members" | i18n + }} + {{ + "groups" | i18n + }} + {{ + reportTabLabel | i18n + }} + {{ + "billing" | i18n + }} + {{ + "settings" | i18n + }} + + diff --git a/apps/web/src/app/organizations/layouts/organization-layout.component.ts b/apps/web/src/app/organizations/layouts/organization-layout.component.ts index c9dcbd5cf3c..3b46a2521a6 100644 --- a/apps/web/src/app/organizations/layouts/organization-layout.component.ts +++ b/apps/web/src/app/organizations/layouts/organization-layout.component.ts @@ -50,49 +50,29 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy { this.organization = await this.organizationService.get(this.organizationId); } - get showManageTab(): boolean { - return NavigationPermissionsService.canAccessManage(this.organization); - } - - get showToolsTab(): boolean { - return NavigationPermissionsService.canAccessTools(this.organization); - } - get showSettingsTab(): boolean { return NavigationPermissionsService.canAccessSettings(this.organization); } - get toolsRoute(): string { - return this.organization.canAccessImportExport - ? "tools/import" - : "tools/exposed-passwords-report"; + get showMembersTab(): boolean { + return NavigationPermissionsService.canAccessMembers(this.organization); } - get manageRoute(): string { - let route: string; - switch (true) { - case this.organization.canManageUsers: - route = "manage/people"; - break; - case this.organization.canViewAssignedCollections || this.organization.canViewAllCollections: - route = "manage/collections"; - break; - case this.organization.canManageGroups: - route = "manage/groups"; - break; - case this.organization.canManagePolicies: - route = "manage/policies"; - break; - case this.organization.canManageSso: - route = "manage/sso"; - break; - case this.organization.canManageScim: - route = "manage/scim"; - break; - case this.organization.canAccessEventLogs: - route = "manage/events"; - break; - } - return route; + get showGroupsTab(): boolean { + return ( + this.organization.useGroups && NavigationPermissionsService.canAccessGroups(this.organization) + ); + } + + get showReportsTab(): boolean { + return NavigationPermissionsService.canAccessReporting(this.organization); + } + + get showBillingTab(): boolean { + return NavigationPermissionsService.canAccessBilling(this.organization); + } + + get reportTabLabel(): string { + return this.organization.useEvents ? "reporting" : "reports"; } } diff --git a/apps/web/src/app/organizations/manage/groups.component.html b/apps/web/src/app/organizations/manage/groups.component.html index 050307b8539..72c6c2ee115 100644 --- a/apps/web/src/app/organizations/manage/groups.component.html +++ b/apps/web/src/app/organizations/manage/groups.component.html @@ -1,77 +1,79 @@ -