From db9e4a549c4b98432c587d6b9962a1e9fbe35cc9 Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Wed, 11 Feb 2026 15:12:24 +0200 Subject: [PATCH 1/4] feat: add subscription page with current plan banner and SAML upgrade gate - Add current plan banner to subscription page with payment settings link - Show upgrade message for SAML SSO when not on Enterprise plan - Rename Pricing tab to Subscription in sidebar Co-Authored-By: Claude Opus 4.5 --- .../profile-sidebar.component.html | 6 +- .../profile-sidebar.component.ts | 2 +- .../src/app/components/sso/sso.component.css | 34 ++++++++++ .../src/app/components/sso/sso.component.html | 15 ++++- .../src/app/components/sso/sso.component.ts | 13 +++- .../components/upgrade/upgrade.component.css | 67 +++++++++++++++++++ .../components/upgrade/upgrade.component.html | 18 ++++- .../components/upgrade/upgrade.component.ts | 11 +-- 8 files changed, 151 insertions(+), 15 deletions(-) diff --git a/frontend/src/app/components/profile/profile-sidebar/profile-sidebar.component.html b/frontend/src/app/components/profile/profile-sidebar/profile-sidebar.component.html index c117fdf29..5f0db5bf8 100644 --- a/frontend/src/app/components/profile/profile-sidebar/profile-sidebar.component.html +++ b/frontend/src/app/components/profile/profile-sidebar/profile-sidebar.component.html @@ -41,13 +41,13 @@ payments - Pricing + Subscription ('account'); + activeTab = input<'account' | 'company' | 'subscription' | 'branding' | 'saml' | 'api' | 'secrets' | 'zapier'>('account'); collapsed = signal(false); initialized = signal(false); diff --git a/frontend/src/app/components/sso/sso.component.css b/frontend/src/app/components/sso/sso.component.css index a0281eb6a..57fc6ed49 100644 --- a/frontend/src/app/components/sso/sso.component.css +++ b/frontend/src/app/components/sso/sso.component.css @@ -61,3 +61,37 @@ margin-top: 16px; padding-bottom: 32px; } + +.upgrade-required { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: 48px 24px; +} + +.upgrade-required__icon { + font-size: 64px; + width: 64px; + height: 64px; + color: rgba(0, 0, 0, 0.38); + margin-bottom: 24px; +} + +@media (prefers-color-scheme: dark) { + .upgrade-required__icon { + color: rgba(255, 255, 255, 0.38); + } +} + +.upgrade-required__description { + color: rgba(0, 0, 0, 0.64); + margin-bottom: 24px; + max-width: 400px; +} + +@media (prefers-color-scheme: dark) { + .upgrade-required__description { + color: rgba(255, 255, 255, 0.7); + } +} diff --git a/frontend/src/app/components/sso/sso.component.html b/frontend/src/app/components/sso/sso.component.html index ec60e6d96..8e7ca0d1e 100644 --- a/frontend/src/app/components/sso/sso.component.html +++ b/frontend/src/app/components/sso/sso.component.html @@ -6,7 +6,20 @@ -
+ + +

SAML SSO Configuration

Configure SAML Single Sign-On for your organization.

diff --git a/frontend/src/app/components/sso/sso.component.ts b/frontend/src/app/components/sso/sso.component.ts index c453e7b00..5aea791f1 100644 --- a/frontend/src/app/components/sso/sso.component.ts +++ b/frontend/src/app/components/sso/sso.component.ts @@ -10,6 +10,7 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { RouterModule } from '@angular/router'; import { Title } from '@angular/platform-browser'; import { SamlConfig, Company } from 'src/app/models/company'; +import { SubscriptionPlans } from 'src/app/models/user'; import { CompanyService } from 'src/app/services/company.service'; import { AlertComponent } from '../ui-components/alert/alert.component'; import { ProfileSidebarComponent } from '../profile/profile-sidebar/profile-sidebar.component'; @@ -36,6 +37,7 @@ import { PlaceholderCompanyComponent } from '../skeletons/placeholder-company/pl }) export class SsoComponent implements OnInit { public company: Company = null; + public hasEnterprisePlan: boolean = false; public samlConfigInitial: SamlConfig = { name: '', @@ -71,9 +73,14 @@ export class SsoComponent implements OnInit { this._company.fetchCompany().subscribe(res => { this.company = res; - this._company.fetchSamlConfiguration(res.id).subscribe((config) => { - if (config.length) this.samlConfig = config[0]; - }); + this.hasEnterprisePlan = res.subscriptionLevel === SubscriptionPlans.enterprise || + res.subscriptionLevel === SubscriptionPlans.enterpriseAnnual; + + if (this.hasEnterprisePlan) { + this._company.fetchSamlConfiguration(res.id).subscribe((config) => { + if (config.length) this.samlConfig = config[0]; + }); + } }); } diff --git a/frontend/src/app/components/upgrade/upgrade.component.css b/frontend/src/app/components/upgrade/upgrade.component.css index 1b0a692a8..b4fd80579 100644 --- a/frontend/src/app/components/upgrade/upgrade.component.css +++ b/frontend/src/app/components/upgrade/upgrade.component.css @@ -28,6 +28,73 @@ width: clamp(300px, 90%, 840px); } +.current-plan-banner { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px; + background: linear-gradient(135deg, var(--color-primaryPalette-50) 0%, var(--color-primaryPalette-100) 100%); + border-radius: 12px; + margin-bottom: 32px; +} + +@media (prefers-color-scheme: dark) { + .current-plan-banner { + background: linear-gradient(135deg, var(--color-primaryPalette-900) 0%, var(--color-primaryPalette-800) 100%); + } +} + +.current-plan-info { + display: flex; + flex-direction: column; + gap: 4px; +} + +.current-plan-label { + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.5px; + color: rgba(0, 0, 0, 0.64); +} + +@media (prefers-color-scheme: dark) { + .current-plan-label { + color: rgba(255, 255, 255, 0.64); + } +} + +.current-plan-name { + font-size: 24px; + font-weight: 500; + color: var(--color-primaryPalette-700); +} + +@media (prefers-color-scheme: dark) { + .current-plan-name { + color: var(--color-primaryPalette-200); + } +} + +.payment-settings-button { + display: flex; + align-items: center; + gap: 8px; +} + +.payment-settings-button mat-icon { + font-size: 20px; + width: 20px; + height: 20px; +} + +@media (width <= 600px) { + .current-plan-banner { + flex-direction: column; + align-items: flex-start; + gap: 16px; + } +} + .header { display: grid; grid-template-columns: 0 7fr repeat(3, 6fr); diff --git a/frontend/src/app/components/upgrade/upgrade.component.html b/frontend/src/app/components/upgrade/upgrade.component.html index 6b55fd8ba..d1969d378 100644 --- a/frontend/src/app/components/upgrade/upgrade.component.html +++ b/frontend/src/app/components/upgrade/upgrade.component.html @@ -1,16 +1,30 @@
- +
+
+
+ Current plan + {{ currentPlan.name }} +
+ + credit_card + Payment settings + +
+

- Manage plans + Compare plans

diff --git a/frontend/src/app/components/upgrade/upgrade.component.ts b/frontend/src/app/components/upgrade/upgrade.component.ts index a0185a946..8b578f31a 100644 --- a/frontend/src/app/components/upgrade/upgrade.component.ts +++ b/frontend/src/app/components/upgrade/upgrade.component.ts @@ -30,15 +30,13 @@ import plans from '../../consts/plans'; styleUrls: ['./upgrade.component.css'] }) export class UpgradeComponent implements OnInit { - public testAlert = { - type: 'info' as const, - message: 'This is a demo alert for the upgrade page.' - }; public currentPlan = { key: PlanKey.Free, price: 0, + name: 'Free', }; public hasPaymentMethod = false; + public portalLink: string = null; public companyId: string; public submitting = false; @@ -188,6 +186,7 @@ export class UpgradeComponent implements OnInit { this.currentPlan = this.getPlan(company.subscriptionLevel); this.companyId = company.id; this.hasPaymentMethod = company.is_payment_method_added; + this.portalLink = company.portal_link; }) } @@ -198,10 +197,12 @@ export class UpgradeComponent implements OnInit { } currentPlanKey = currentPlanKey.slice(0, -5).toLowerCase(); + const planData = plans.find(plan => plan.key === currentPlanKey); return { key: currentPlanKey as PlanKey, - price: plans.find(plan => plan.key === currentPlanKey).price, + price: planData?.price || 0, + name: planData?.name || 'Free', }; } From debaaee05737d38d490c184e3c897889c98e8ea2 Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Wed, 11 Feb 2026 15:20:14 +0200 Subject: [PATCH 2/4] feat: add upgrade gates and UI improvements - Remove subscription section from Company page (moved to Subscription) - Add white-label upgrade gate on Branding page for free plan users - Improve dark theme text colors on subscription banner - Add top margin to create secret dialog input Co-Authored-By: Claude Opus 4.5 --- .../branding/branding.component.css | 42 +++++++++++++++++++ .../branding/branding.component.html | 12 +++++- .../components/branding/branding.component.ts | 2 + .../components/company/company.component.css | 33 --------------- .../components/company/company.component.html | 26 ------------ .../create-secret-dialog.component.css | 4 ++ .../components/upgrade/upgrade.component.css | 6 ++- 7 files changed, 64 insertions(+), 61 deletions(-) diff --git a/frontend/src/app/components/branding/branding.component.css b/frontend/src/app/components/branding/branding.component.css index ffb923ac0..d8ce8a2ba 100644 --- a/frontend/src/app/components/branding/branding.component.css +++ b/frontend/src/app/components/branding/branding.component.css @@ -171,3 +171,45 @@ background-color: var(--color-accentedPalette-700); } } + +.upgrade-required { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: 48px 24px; + border: 1px solid var(--color-primaryPalette-100); + height: fit-content; +} + +@media (prefers-color-scheme: dark) { + .upgrade-required { + border-color: var(--color-primaryPalette-700); + } +} + +.upgrade-required__icon { + font-size: 64px; + width: 64px; + height: 64px; + color: rgba(0, 0, 0, 0.38); + margin-bottom: 24px; +} + +@media (prefers-color-scheme: dark) { + .upgrade-required__icon { + color: rgba(255, 255, 255, 0.38); + } +} + +.upgrade-required__description { + color: rgba(0, 0, 0, 0.64); + margin-bottom: 24px; + max-width: 400px; +} + +@media (prefers-color-scheme: dark) { + .upgrade-required__description { + color: rgba(255, 255, 255, 0.7); + } +} diff --git a/frontend/src/app/components/branding/branding.component.html b/frontend/src/app/components/branding/branding.component.html index 54243b1be..a803f4c9f 100644 --- a/frontend/src/app/components/branding/branding.component.html +++ b/frontend/src/app/components/branding/branding.component.html @@ -204,7 +204,7 @@

Branding

-
+

Configure DNS Records

These instructions will guide you in setting up domain to have your admin panel on it. @@ -224,6 +224,16 @@

Configure DNS Records


Done! Now wait for the server's updates; it might take 1-2 hours.

+
+ lock +

White-label is available on Team plan

+

+ Upgrade to enable white-label settings for your organization. +

+ + Upgrade + +
diff --git a/frontend/src/app/components/branding/branding.component.ts b/frontend/src/app/components/branding/branding.component.ts index 1e7f308d8..762bfca24 100644 --- a/frontend/src/app/components/branding/branding.component.ts +++ b/frontend/src/app/components/branding/branding.component.ts @@ -7,6 +7,7 @@ import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatTooltipModule } from '@angular/material/tooltip'; import { NgIf } from '@angular/common'; +import { RouterModule } from '@angular/router'; import { Angulartics2, Angulartics2OnModule } from 'angulartics2'; import { Subscription } from 'rxjs'; import { Title } from '@angular/platform-browser'; @@ -27,6 +28,7 @@ import { PlaceholderCompanyComponent } from '../skeletons/placeholder-company/pl imports: [ NgIf, FormsModule, + RouterModule, MatFormFieldModule, MatInputModule, MatButtonModule, diff --git a/frontend/src/app/components/company/company.component.css b/frontend/src/app/components/company/company.component.css index 88bdccfd3..2b9146bc8 100644 --- a/frontend/src/app/components/company/company.component.css +++ b/frontend/src/app/components/company/company.component.css @@ -48,39 +48,6 @@ gap: 4px; } -.company-plan { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 32px; -} - -.company-plan-name { - text-transform: capitalize; -} - -.company-plan__paymnent-buttons { - display: flex; - gap: 12px; - margin-left: auto; -} - -@media (width <= 600px) { - .upgrade-button__caption_desktop { - display: none; - } -} - -.upgrade-button__caption_mobile { - display: none; -} - -@media (width <= 600px) { - .upgrade-button__caption_mobile { - display: initial; - } -} - .tableHeader { display: flex; align-items: center; diff --git a/frontend/src/app/components/company/company.component.html b/frontend/src/app/components/company/company.component.html index b9d84b6e8..6a33b53ae 100644 --- a/frontend/src/app/components/company/company.component.html +++ b/frontend/src/app/components/company/company.component.html @@ -33,32 +33,6 @@

- -

Members (max 3)

diff --git a/frontend/src/app/components/secrets/create-secret-dialog/create-secret-dialog.component.css b/frontend/src/app/components/secrets/create-secret-dialog/create-secret-dialog.component.css index 8a7f2ee2f..6052b0629 100644 --- a/frontend/src/app/components/secrets/create-secret-dialog/create-secret-dialog.component.css +++ b/frontend/src/app/components/secrets/create-secret-dialog/create-secret-dialog.component.css @@ -3,6 +3,10 @@ margin-bottom: 16px; } +.full-width:first-child { + margin-top: 12px; +} + .master-encryption-section { margin-top: 8px; padding: 16px; diff --git a/frontend/src/app/components/upgrade/upgrade.component.css b/frontend/src/app/components/upgrade/upgrade.component.css index b4fd80579..8b099bc07 100644 --- a/frontend/src/app/components/upgrade/upgrade.component.css +++ b/frontend/src/app/components/upgrade/upgrade.component.css @@ -70,8 +70,12 @@ } @media (prefers-color-scheme: dark) { + .current-plan-label { + color: rgba(255, 255, 255, 0.7); + } + .current-plan-name { - color: var(--color-primaryPalette-200); + color: #fff; } } From ea9a9cf02a50ef85f80f857d6e4f4715d20b4456 Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Thu, 12 Feb 2026 14:23:26 +0000 Subject: [PATCH 3/4] company settings: set up visibility of elements depending on company role and saas/self-hosted version --- .../branding/branding.component.html | 12 ++-- .../components/company/company.component.html | 8 --- .../profile-sidebar.component.html | 1 + .../components/upgrade/upgrade.component.html | 56 ++++++++++--------- .../components/upgrade/upgrade.component.ts | 7 +++ frontend/src/environments/environment.dev.ts | 2 +- 6 files changed, 44 insertions(+), 42 deletions(-) diff --git a/frontend/src/app/components/branding/branding.component.html b/frontend/src/app/components/branding/branding.component.html index 6865aa9aa..97b4f15de 100644 --- a/frontend/src/app/components/branding/branding.component.html +++ b/frontend/src/app/components/branding/branding.component.html @@ -12,9 +12,9 @@

Branding

-
+ [matTooltip]="currentUser.role !== 'ADMIN' ? 'Contact your Account Owner to set up white label settings.' : 'To white‑label your domain, please upgrade to the Team plan or higher.'">
Branding

angularticsAction="Company: custom domain is edited" (change)="posthog.capture('Company: custom domain is edited')" placeholder="e.g. {{companyCustomDomainPlaceholder}}" - [readonly]="currentUser.role === 'DB_ADMIN' || isCustomDomain" + [readonly]="currentUser.role !== 'ADMIN' || isCustomDomain" [(ngModel)]="companyCustomDomainHostname"> To change the domain, visit app.rocketadmin.com/company @@ -48,7 +48,7 @@

Branding

(click)="handleDeleteDomainDialogOpen()"> Delete - @@ -57,7 +57,7 @@

Branding

-
+
-
-
-
- Current plan: - {{currentPlan}} -
-
-

Members (max 3)

diff --git a/frontend/src/app/components/profile/profile-sidebar/profile-sidebar.component.html b/frontend/src/app/components/profile/profile-sidebar/profile-sidebar.component.html index 5f0db5bf8..2e7a48052 100644 --- a/frontend/src/app/components/profile/profile-sidebar/profile-sidebar.component.html +++ b/frontend/src/app/components/profile/profile-sidebar/profile-sidebar.component.html @@ -60,6 +60,7 @@ Branding
-
+
diff --git a/frontend/src/app/components/upgrade/upgrade.component.ts b/frontend/src/app/components/upgrade/upgrade.component.ts index 8b578f31a..22f7419aa 100644 --- a/frontend/src/app/components/upgrade/upgrade.component.ts +++ b/frontend/src/app/components/upgrade/upgrade.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { AlertComponent } from '../ui-components/alert/alert.component'; import { CommonModule } from '@angular/common'; +import { CompanyMemberRole } from 'src/app/models/company'; import { CompanyService } from 'src/app/services/company.service'; import { MatButtonModule } from '@angular/material/button'; import { MatChipsModule } from '@angular/material/chips'; @@ -11,6 +12,7 @@ import { PaymentService } from 'src/app/services/payment.service'; import { PlanKey } from 'src/app/models/plans'; import { ProfileSidebarComponent } from '../profile/profile-sidebar/profile-sidebar.component'; import { RouterModule } from '@angular/router'; +import { UserService } from 'src/app/services/user.service'; import plans from '../../consts/plans'; @Component({ @@ -39,6 +41,7 @@ export class UpgradeComponent implements OnInit { public portalLink: string = null; public companyId: string; public submitting = false; + public isAdmin = false; databases = [ { @@ -175,10 +178,14 @@ export class UpgradeComponent implements OnInit { constructor( private _paymentService: PaymentService, private _company: CompanyService, + private _userService: UserService, ) { } ngOnInit(): void { this.getCompanyPaln(); + this._userService.cast.subscribe((user) => { + this.isAdmin = user.role === CompanyMemberRole.CAO; + }); } getCompanyPaln() { diff --git a/frontend/src/environments/environment.dev.ts b/frontend/src/environments/environment.dev.ts index 9490b3494..24d2881ea 100644 --- a/frontend/src/environments/environment.dev.ts +++ b/frontend/src/environments/environment.dev.ts @@ -1,6 +1,6 @@ export const environment = { production: false, - saas: false, + saas: true, apiRoot: 'https://app.rocketadmin.com/api', saasURL: 'https://app.rocketadmin.com', saasHostnames: ['localhost', '127.0.0.1'], From d08de29bf74220b6350d304d42a1cdd5a83873bc Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Thu, 12 Feb 2026 14:45:08 +0000 Subject: [PATCH 4/4] fix unit tests --- frontend/src/app/components/sso/sso.component.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/components/sso/sso.component.spec.ts b/frontend/src/app/components/sso/sso.component.spec.ts index 3380fbb92..510354fc1 100644 --- a/frontend/src/app/components/sso/sso.component.spec.ts +++ b/frontend/src/app/components/sso/sso.component.spec.ts @@ -16,7 +16,7 @@ describe('SsoComponent', () => { name: 'Test Company', address: {}, portal_link: '', - subscriptionLevel: 'FREE_PLAN', + subscriptionLevel: 'ENTERPRISE_PLAN', connections: [], invitations: [], is_payment_method_added: false,