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 @@ -