From d79a5d0f749440790381ef1ff6be73b3b22d5a90 Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 13 Apr 2025 10:57:09 +0300 Subject: [PATCH 1/4] white label: - company tab title; - update preview. --- frontend/src/app/app-routing.module.ts | 2 +- frontend/src/app/app.component.ts | 2 - .../components/company/company.component.css | 10 +- .../components/company/company.component.html | 96 ++++++++++++------- .../components/company/company.component.ts | 56 +++++++++-- .../connect-db/connect-db.component.ts | 4 +- .../db-table-widgets.component.ts | 2 +- frontend/src/app/services/company.service.ts | 52 +++++++++- 8 files changed, 174 insertions(+), 50 deletions(-) diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index db710e9a2..5585fb7af 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -45,7 +45,7 @@ const routes: Routes = [ {path: 'user-settings', component: UserSettingsComponent, canActivate: [AuthGuard], title: 'User settings | Rocketadmin'}, // company routes have to be in this specific order {path: 'company/:company-id/verify/:verification-token', pathMatch: 'full', component: CompanyMemberInvitationComponent, title: 'Invitation | Rocketadmin'}, - {path: 'company', pathMatch: 'full', component: CompanyComponent, title: 'Company settings | Rocketadmin', canActivate: [AuthGuard]}, + {path: 'company', pathMatch: 'full', component: CompanyComponent, canActivate: [AuthGuard]}, {path: 'change-password', component: PasswordChangeComponent, canActivate: [AuthGuard]}, {path: 'upgrade', component: UpgradeComponent, canActivate: [AuthGuard], title: 'Upgrade | Rocketadmin'}, {path: 'upgrade/payment', component: PaymentFormComponent, canActivate: [AuthGuard], title: 'Payment | Rocketadmin'}, diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index 797e18700..d731777ca 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -260,8 +260,6 @@ export class AppComponent { document.head.appendChild(favicon16); document.head.appendChild(favicon32); } - - // this.whiteLabelSettingsLoaded = true; }) this._uiSettings.getUiSettings().subscribe(settings => { this.isFeatureNotificationShown = (settings?.globalSettings?.lastFeatureNotificationId !== this.currentFeatureNotificationId) diff --git a/frontend/src/app/components/company/company.component.css b/frontend/src/app/components/company/company.component.css index 8a1f3eeae..340a97390 100644 --- a/frontend/src/app/components/company/company.component.css +++ b/frontend/src/app/components/company/company.component.css @@ -263,16 +263,22 @@ position: relative; } +.white-label-settings-images { + display: flex; + gap: 24px; + margin-top: 16px; + margin-bottom: 24px; +} + .upload-logo-form { display: flex; align-items: center; gap: 8px; - margin-top: 8px; } .white-label-preview { height: auto; - margin-top: 20px; + margin-top: 8px; width: 100%; } diff --git a/frontend/src/app/components/company/company.component.html b/frontend/src/app/components/company/company.component.html index 0d9c4d3ce..30a3b9aca 100644 --- a/frontend/src/app/components/company/company.component.html +++ b/frontend/src/app/components/company/company.component.html @@ -258,32 +258,66 @@

White label

-
-
- + +
+ + - - +
+ +
+
+ + +
+ + +
+ - - -
-
- + -
- -
@@ -319,17 +353,15 @@

White label

- - - - - - - - - - - + + + + diff --git a/frontend/src/app/components/company/company.component.ts b/frontend/src/app/components/company/company.component.ts index 94cbde729..b41fb0041 100644 --- a/frontend/src/app/components/company/company.component.ts +++ b/frontend/src/app/components/company/company.component.ts @@ -26,6 +26,8 @@ import { PlaceholderTableDataComponent } from '../skeletons/placeholder-table-da import { NgIf } from '@angular/common'; import { RouterModule } from '@angular/router'; import { DeleteDomainDialogComponent } from './delete-domain-dialog/delete-domain-dialog.component'; +import { Title } from '@angular/platform-browser'; +import { Subscription } from 'rxjs'; @Component({ selector: 'app-company', @@ -68,11 +70,11 @@ export class CompanyComponent { public companyCustomDomain: { id: string, companyId: string, - hostname: string + hostname: string, } = { id: null, companyId: '', - hostname: '' + hostname: '', }; public companyCustomDomainHostname: string; @@ -84,17 +86,21 @@ export class CompanyComponent { public submittingLogo: boolean = false; public submittingFavicon: boolean = false; - get whiteLabelSettings(): {logo: string, favicon: string} { - return this._company.whiteLabelSettings || { logo: '', favicon: '' }; + public companyTabTitle: string; + public submittingTabTitle: boolean = false; + + get whiteLabelSettings(): {logo: string, favicon: string, tabTitle: string} { + return this._company.whiteLabelSettings || { logo: '', favicon: '', tabTitle : '' }; } + private getTitleSubscription: Subscription; + constructor( public _company: CompanyService, public _user: UserService, - // private _notifications: NotificationsService, public dialog: MatDialog, private angulartics2: Angulartics2, - // private title: Title + private title: Title ) { } ngOnInit() { @@ -103,6 +109,11 @@ export class CompanyComponent { this.isCustomDomain = true; } + this.getTitleSubscription = this._company.getCurrentTabTitle().subscribe(title => { + this.companyTabTitle = title; + this.title.setTitle(`Company settings | ${title || 'Rocketadmin'}`); + }); + this._company.fetchCompany().subscribe(res => { this.company = res; this.setCompanyPlan(res.subscriptionLevel); @@ -127,14 +138,19 @@ export class CompanyComponent { this.getCompanyMembers(this.company.id); } else if (arg === 'domain') { this.getCompanyCustomDomain(this.company.id); - } - else if (arg === 'updated-white-label-settings') { + } else if (arg === 'updated-white-label-settings') { // this.submittingLogo = true; this._company.getWhiteLabelProperties(this.company.id).subscribe(); - }; + } }); } + ngOnDestroy() { + if (this.getTitleSubscription) { + this.getTitleSubscription.unsubscribe(); + } + } + getCompanyMembers(companyId: string) { this._company.fetchCompanyMembers(companyId).subscribe(res => { if (this.company.invitations) { @@ -372,4 +388,26 @@ export class CompanyComponent { this.submittingFavicon = false; }); } + + updateTabTitle() { + this.submittingTabTitle = true; + this._company.updateTabTitle(this.company.id, this.companyTabTitle).subscribe(() => { + this.submittingTabTitle = false; + this.angulartics2.eventTrack.next({ + action: 'Company: tab title is updated successfully', + }); + }, err => { + this.submittingTabTitle = false; + }); + } + + deleteTabTitle() { + this.submittingTabTitle = true; + this._company.removeTabTitle(this.company.id).subscribe(() => { + this.submittingTabTitle = false; + this.angulartics2.eventTrack.next({ + action: 'Company: tab title is deleted successfully', + }); + }); + } } diff --git a/frontend/src/app/components/connect-db/connect-db.component.ts b/frontend/src/app/components/connect-db/connect-db.component.ts index 7fe35917b..1f2b03c57 100644 --- a/frontend/src/app/components/connect-db/connect-db.component.ts +++ b/frontend/src/app/components/connect-db/connect-db.component.ts @@ -42,6 +42,7 @@ import { UserService } from 'src/app/services/user.service'; import { environment } from 'src/environments/environment'; import googlIPsList from 'src/app/consts/google-IP-addresses'; import isIP from 'validator/lib/isIP'; +import { CompanyService } from 'src/app/services/company.service'; @Component({ selector: 'app-connect-db', @@ -103,6 +104,7 @@ export class ConnectDBComponent implements OnInit, OnDestroy { private _connections: ConnectionsService, private _notifications: NotificationsService, public _user: UserService, + private _company: CompanyService, private ngZone: NgZone, public router: Router, public dialog: MatDialog, @@ -114,7 +116,7 @@ export class ConnectDBComponent implements OnInit, OnDestroy { this.connectionID = this._connections.currentConnectionID; if (this.connectionID) this.getTitleSubscription = this._connections.getCurrentConnectionTitle().subscribe(connectionTitle => { - this.title.setTitle(`Edit connection ${connectionTitle} | Rocketadmin`); + this.title.setTitle(`Edit connection ${connectionTitle} | ${this._company.companyTabTitle || 'Rocketadmin'}`); }); if (!this.connectionID) { diff --git a/frontend/src/app/components/dashboard/db-table-widgets/db-table-widgets.component.ts b/frontend/src/app/components/dashboard/db-table-widgets/db-table-widgets.component.ts index 70ce2c9b2..e932cd4f2 100644 --- a/frontend/src/app/components/dashboard/db-table-widgets/db-table-widgets.component.ts +++ b/frontend/src/app/components/dashboard/db-table-widgets/db-table-widgets.component.ts @@ -194,7 +194,7 @@ export class DbTableWidgetsComponent implements OnInit { this.fieldsCount = res.structure.length; this.fields = res.structure.map((field: TableField) => field.column_name); this.dispalyTableName = res.display_name || normalizeTableName(this.tableName); - this.title.setTitle(`${this.dispalyTableName} - Add new record | Rocketadmin`); + this.title.setTitle(`${this.dispalyTableName} - Field display | Rocketadmin`); this.getWidgets(); }) this.codeEditorTheme = this._uiSettings.editorTheme; diff --git a/frontend/src/app/services/company.service.ts b/frontend/src/app/services/company.service.ts index c67990624..167ae1e72 100644 --- a/frontend/src/app/services/company.service.ts +++ b/frontend/src/app/services/company.service.ts @@ -16,8 +16,11 @@ export class CompanyService { private company = new BehaviorSubject(''); public cast = this.company.asObservable(); + private companyTabTitleSubject: BehaviorSubject = new BehaviorSubject('Rocketadmin'); + private companyLogo: string; private companyFavicon: string; + public companyTabTitle: string; constructor( private _http: HttpClient, @@ -28,10 +31,15 @@ export class CompanyService { get whiteLabelSettings() { return { logo: this.companyLogo, - favicon: this.companyFavicon + favicon: this.companyFavicon, + tabTitle: this.companyTabTitle, }; } + getCurrentTabTitle() { + return this.companyTabTitleSubject.asObservable(); + } + fetchCompany() { return this._http.get(`/company/my/full`) .pipe( @@ -396,6 +404,38 @@ export class CompanyService { ); } + updateTabTitle(companyId: string, tab_title: string) { + return this._http.post(`/company/tab-title/${companyId}`, {tab_title}) + .pipe( + map(res => { + this._notifications.showSuccessSnackbar('Tab title has been saved. Please rerefresh the page to see the changes.'); + this.company.next('updated-white-label-settings'); + return res + }), + catchError((err) => { + console.log(err); + this._notifications.showErrorSnackbar(err.error.message || err.message); + return EMPTY; + }) + ); + } + + removeTabTitle(companyId: string) { + return this._http.delete(`/company/tab-title/${companyId}`) + .pipe( + map(res => { + this._notifications.showSuccessSnackbar('Tab title has been removed. Please rerefresh the page to see the changes.'); + this.company.next('updated-white-label-settings'); + return res + }), + catchError((err) => { + console.log(err); + this._notifications.showErrorSnackbar(err.error.message || err.message); + return EMPTY; + }) + ); + } + getWhiteLabelProperties(companyId: string) { return this._http.get(`/company/white-label-properties/${companyId}`) @@ -413,9 +453,18 @@ export class CompanyService { this.companyFavicon = null; } + if (res.tab_title) { + this.companyTabTitle = res.tab_title; + } else { + this.companyTabTitle = null; + } + + this.companyTabTitleSubject.next(res.tab_title); + return { logo: this.companyLogo, favicon: this.companyFavicon, + tab_title: res.tab_title, } }), catchError((err) => { @@ -425,5 +474,4 @@ export class CompanyService { }) ); } - } From 1db90170585f42e61f30c0f14476b5a2b4b12bff Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 13 Apr 2025 12:02:56 +0300 Subject: [PATCH 2/4] white label: update tab titles --- frontend/src/app/app-routing.module.ts | 6 +++--- .../app/components/audit/audit.component.ts | 14 +++++++------- .../connect-db/connect-db.component.ts | 18 ++++++++++-------- .../connection-settings.component.ts | 4 +++- .../connections-list.component.ts | 11 +++++++++++ .../dashboard/dashboard.component.ts | 8 +++++--- .../db-table-actions.component.ts | 2 +- .../db-table-settings.component.ts | 4 +++- .../db-table-widgets.component.ts | 4 +++- .../db-table-row-edit.component.ts | 4 +++- .../user-settings/user-settings.component.ts | 5 +++++ .../app/components/users/users.component.ts | 2 +- 12 files changed, 55 insertions(+), 27 deletions(-) diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 5585fb7af..2d65c8d02 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -40,9 +40,9 @@ const routes: Routes = [ {path: 'external/user/email/verify/:verification-token', component: EmailVerificationComponent, title: 'Email verification | Rocketadmin'}, {path: 'external/user/email/change/verify/:change-token', component: EmailChangeComponent, title: 'Email updating | Rocketadmin'}, {path: 'deleted', component: UserDeletedSuccessComponent, title: 'User deleted | Rocketadmin'}, - {path: 'connect-db', component: ConnectDBComponent, canActivate: [AuthGuard], title: 'Add new database | Rocketadmin'}, - {path: 'connections-list', component: ConnectionsListComponent, canActivate: [AuthGuard], title: 'Connections | Rocketadmin'}, - {path: 'user-settings', component: UserSettingsComponent, canActivate: [AuthGuard], title: 'User settings | Rocketadmin'}, + {path: 'connect-db', component: ConnectDBComponent, canActivate: [AuthGuard]}, + {path: 'connections-list', component: ConnectionsListComponent, canActivate: [AuthGuard]}, + {path: 'user-settings', component: UserSettingsComponent, canActivate: [AuthGuard]}, // company routes have to be in this specific order {path: 'company/:company-id/verify/:verification-token', pathMatch: 'full', component: CompanyMemberInvitationComponent, title: 'Invitation | Rocketadmin'}, {path: 'company', pathMatch: 'full', component: CompanyComponent, canActivate: [AuthGuard]}, diff --git a/frontend/src/app/components/audit/audit.component.ts b/frontend/src/app/components/audit/audit.component.ts index 8a1303028..78f2f374c 100644 --- a/frontend/src/app/components/audit/audit.component.ts +++ b/frontend/src/app/components/audit/audit.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { AsyncPipe, NgClass, NgForOf, NgIf } from '@angular/common'; import { Subscription, merge } from 'rxjs'; @@ -27,6 +27,7 @@ import { normalizeTableName } from 'src/app/lib/normalize'; import { tap } from 'rxjs/operators'; import { BannerComponent } from '../ui-components/banner/banner.component'; import { PlaceholderTableDataComponent } from '../skeletons/placeholder-table-data/placeholder-table-data.component'; +import { CompanyService } from 'src/app/services/company.service'; @Component({ selector: 'app-audit', @@ -50,7 +51,7 @@ import { PlaceholderTableDataComponent } from '../skeletons/placeholder-table-da templateUrl: './audit.component.html', styleUrls: ['./audit.component.css'] }) -export class AuditComponent implements OnInit, OnDestroy { +export class AuditComponent implements OnInit { public isSaas = (environment as any).saas; public connectionID: string; public accesLevel: string; @@ -73,6 +74,7 @@ export class AuditComponent implements OnInit, OnDestroy { private _connections: ConnectionsService, private _tables: TablesService, private _users: UsersService, + private _companyService: CompanyService, public dialog: MatDialog, private title: Title ) { } @@ -89,7 +91,9 @@ export class AuditComponent implements OnInit, OnDestroy { ngOnInit(): void { this.getTitleSubscription = this._connections.getCurrentConnectionTitle().subscribe(connectionTitle => { - this.title.setTitle(`Audit - ${connectionTitle} | Rocketadmin`); + this.title.setTitle(`Audit - ${connectionTitle} | ${this._companyService.companyTabTitle || 'Rocketadmin'}`); + + this.getTitleSubscription.unsubscribe(); }); this.connectionID = this._connections.currentConnectionID; this.accesLevel = this._connections.currentConnectionAccessLevel; @@ -120,10 +124,6 @@ export class AuditComponent implements OnInit, OnDestroy { }) } - ngOnDestroy() { - this.getTitleSubscription.unsubscribe(); - } - loadLogsPage() { this.dataSource.fetchLogs({ connectionID: this.connectionID, diff --git a/frontend/src/app/components/connect-db/connect-db.component.ts b/frontend/src/app/components/connect-db/connect-db.component.ts index 1f2b03c57..57e37e2cb 100644 --- a/frontend/src/app/components/connect-db/connect-db.component.ts +++ b/frontend/src/app/components/connect-db/connect-db.component.ts @@ -2,7 +2,7 @@ import * as ipaddr from 'ipaddr.js'; import { Alert, AlertActionType, AlertType } from 'src/app/models/alert'; import { Angulartics2, Angulartics2Module } from 'angulartics2'; -import { Component, NgZone, OnDestroy, OnInit } from '@angular/core'; +import { Component, NgZone, OnInit } from '@angular/core'; import { Connection, ConnectionType, DBtype, TestConnection } from 'src/app/models/connection'; import { AccessLevel } from 'src/app/models/user'; @@ -74,7 +74,7 @@ import { CompanyService } from 'src/app/services/company.service'; Angulartics2Module ] }) -export class ConnectDBComponent implements OnInit, OnDestroy { +export class ConnectDBComponent implements OnInit { public isSaas = (environment as any).saas; public connectionID: string | null = null; @@ -115,8 +115,14 @@ export class ConnectDBComponent implements OnInit, OnDestroy { ngOnInit() { this.connectionID = this._connections.currentConnectionID; - if (this.connectionID) this.getTitleSubscription = this._connections.getCurrentConnectionTitle().subscribe(connectionTitle => { - this.title.setTitle(`Edit connection ${connectionTitle} | ${this._company.companyTabTitle || 'Rocketadmin'}`); + this.getTitleSubscription = this._connections.getCurrentConnectionTitle().subscribe(connectionTitle => { + if (this.connectionID) { + this.title.setTitle(`Credentials — ${connectionTitle} | ${this._company.companyTabTitle || 'Rocketadmin'}`); + } else { + this.title.setTitle(`Add new database | ${this._company.companyTabTitle || 'Rocketadmin'}`); + } + + this.getTitleSubscription.unsubscribe(); }); if (!this.connectionID) { @@ -128,10 +134,6 @@ export class ConnectDBComponent implements OnInit, OnDestroy { }; } - ngOnDestroy() { - if (this.connectionID && !this.connectionToken) this.getTitleSubscription.unsubscribe(); - } - get db():Connection { return this._connections.currentConnection; } diff --git a/frontend/src/app/components/connection-settings/connection-settings.component.ts b/frontend/src/app/components/connection-settings/connection-settings.component.ts index 1946253a8..5eb7a02b7 100644 --- a/frontend/src/app/components/connection-settings/connection-settings.component.ts +++ b/frontend/src/app/components/connection-settings/connection-settings.component.ts @@ -25,6 +25,7 @@ import { PlaceholderConnectionSettingsComponent } from '../skeletons/placeholder import { AlertComponent } from '../ui-components/alert/alert.component'; import { ZapierComponent } from './zapier/zapier.component'; import { MatTabsModule } from '@angular/material/tabs'; +import { CompanyService } from 'src/app/services/company.service'; @Component({ selector: 'app-connection-settings', @@ -76,13 +77,14 @@ export class ConnectionSettingsComponent implements OnInit, OnDestroy { constructor( private _connections: ConnectionsService, private _tables: TablesService, + private _company: CompanyService, private title: Title, @Inject(Angulartics2) private angulartics2: Angulartics2 ) { } ngOnInit(): void { this.getTitleSubscription = this._connections.getCurrentConnectionTitle().subscribe(connectionTitle => { - this.title.setTitle(`Settings - ${connectionTitle} | Rocketadmin`); + this.title.setTitle(`Settings - ${connectionTitle} | ${this._company.companyTabTitle || 'Rocketadmin'}`); }); this.connectionID = this._connections.currentConnectionID; diff --git a/frontend/src/app/components/connections-list/connections-list.component.ts b/frontend/src/app/components/connections-list/connections-list.component.ts index ff0fed519..36ffae168 100644 --- a/frontend/src/app/components/connections-list/connections-list.component.ts +++ b/frontend/src/app/components/connections-list/connections-list.component.ts @@ -16,6 +16,8 @@ import { UiSettings } from 'src/app/models/ui-settings'; import { UiSettingsService } from 'src/app/services/ui-settings.service'; import { User } from 'src/app/models/user'; import { UserService } from 'src/app/services/user.service'; +import { Title } from '@angular/platform-browser'; +import { Subscription } from 'rxjs'; @Component({ selector: 'app-connections-list', @@ -42,15 +44,24 @@ export class ConnectionsListComponent implements OnInit { public companyName: string; public currentUser: User; + private getTitleSubscription: Subscription; + constructor( private _connectionsServise: ConnectionsService, public deleteDialog: MatDialog, private _userService: UserService, private _companyService: CompanyService, private _uiSettings: UiSettingsService, + private title: Title ) { } ngOnInit(): void { + this.getTitleSubscription = this._companyService.getCurrentTabTitle().subscribe(tabTitle => { + this.title.setTitle(`Connections | ${tabTitle || 'Rocketadmin'}`); + + this.getTitleSubscription.unsubscribe(); + }); + this._userService.cast.subscribe(user => { this.currentUser = user; user.id && this._companyService.fetchCompanyName(user.company.id) diff --git a/frontend/src/app/components/dashboard/dashboard.component.ts b/frontend/src/app/components/dashboard/dashboard.component.ts index 76e69999e..52e916c5d 100644 --- a/frontend/src/app/components/dashboard/dashboard.component.ts +++ b/frontend/src/app/components/dashboard/dashboard.component.ts @@ -39,6 +39,7 @@ import { environment } from 'src/environments/environment'; import { getComparatorsFromUrl } from 'src/app/lib/parse-filter-params'; import { normalizeTableName } from '../../lib/normalize' import { omitBy } from "lodash"; +import { CompanyService } from 'src/app/services/company.service'; interface DataToActivateActions { action: CustomEvent, @@ -107,6 +108,7 @@ export class DashboardComponent implements OnInit, OnDestroy { private _tableRow: TableRowService, private _uiSettings: UiSettingsService, private _tableState: TableStateService, + private _company: CompanyService, public router: Router, private route: ActivatedRoute, public dialog: MatDialog, @@ -163,7 +165,7 @@ export class DashboardComponent implements OnInit, OnDestroy { } catch(err) { this.loading = false; this.isServerError = true; - this.title.setTitle('Dashboard | Rocketadmin'); + this.title.setTitle(`Dashboard | ${this._company.companyTabTitle || 'Rocketadmin'}`); if (err instanceof HttpErrorResponse) { this.serverError = {abstract: err.error.message || err.message, details: err.error.originalMessage}; @@ -173,7 +175,7 @@ export class DashboardComponent implements OnInit, OnDestroy { if (tables && tables.length === 0) { this.noTablesError = true; this.loading = false; - this.title.setTitle('No tables | Rocketadmin'); + this.title.setTitle(`No tables | ${this._company.companyTabTitle || 'Rocketadmin'}`); } else if (tables) { this.formatTableNames(tables); this.route.paramMap @@ -183,7 +185,7 @@ export class DashboardComponent implements OnInit, OnDestroy { if (tableName) { this.selectedTableName = tableName; this.setTable(tableName); - this.title.setTitle(`${this.selectedTableDisplayName} table | Rocketadmin`); + this.title.setTitle(`${this.selectedTableDisplayName} table | ${this._company.companyTabTitle || 'Rocketadmin'}`); this.selection.clear(); } else { if (this.defaultTableToOpen) { diff --git a/frontend/src/app/components/dashboard/db-table-actions/db-table-actions.component.ts b/frontend/src/app/components/dashboard/db-table-actions/db-table-actions.component.ts index c3a925c22..457bf6041 100644 --- a/frontend/src/app/components/dashboard/db-table-actions/db-table-actions.component.ts +++ b/frontend/src/app/components/dashboard/db-table-actions/db-table-actions.component.ts @@ -128,7 +128,7 @@ export class DbTableActionsComponent implements OnInit { console.log(this.rulesData); this.rules = this.rulesData.action_rules; if (this.rules.length) this.setSelectedRule(this.rules[0]); - this.title.setTitle(`${this.rulesData.display_name || this.normalizedTableName} - Actions | Rocketadmin`); + this.title.setTitle(`${this.rulesData.display_name || this.normalizedTableName} - Actions | ${this._company.companyTabTitle || 'Rocketadmin'}`); } catch(error) { if (error instanceof HttpErrorResponse) { this.rulesData = null; diff --git a/frontend/src/app/components/dashboard/db-table-settings/db-table-settings.component.ts b/frontend/src/app/components/dashboard/db-table-settings/db-table-settings.component.ts index 0b0ed5f47..af278a4ff 100644 --- a/frontend/src/app/components/dashboard/db-table-settings/db-table-settings.component.ts +++ b/frontend/src/app/components/dashboard/db-table-settings/db-table-settings.component.ts @@ -26,6 +26,7 @@ import { Title } from '@angular/platform-browser'; import { normalizeTableName } from 'src/app/lib/normalize'; import { MatButtonModule } from '@angular/material/button'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { CompanyService } from 'src/app/services/company.service'; @Component({ selector: 'app-db-table-settings', @@ -90,6 +91,7 @@ export class DbTableSettingsComponent implements OnInit { private _tables: TablesService, private _connections: ConnectionsService, private _location: Location, + private _company: CompanyService, public router: Router, private title: Title, private angulartics2: Angulartics2, @@ -148,7 +150,7 @@ export class DbTableSettingsComponent implements OnInit { if (Object.keys(res).length === 0 || (res && res.list_fields && !res.list_fields.length)) { this.listFieldsOrder = [...this.fields]; }; - this.title.setTitle(`${res.display_name || this.displayTableName} - Table settings | Rocketadmin`); + this.title.setTitle(`${res.display_name || this.displayTableName} - Table settings | ${this._company.companyTabTitle || 'Rocketadmin'}`); } ); } diff --git a/frontend/src/app/components/dashboard/db-table-widgets/db-table-widgets.component.ts b/frontend/src/app/components/dashboard/db-table-widgets/db-table-widgets.component.ts index e932cd4f2..447456534 100644 --- a/frontend/src/app/components/dashboard/db-table-widgets/db-table-widgets.component.ts +++ b/frontend/src/app/components/dashboard/db-table-widgets/db-table-widgets.component.ts @@ -32,6 +32,7 @@ import { TextRowComponent } from '../../ui-components/row-fields/text/text.compo import { LongTextRowComponent } from '../../ui-components/row-fields/long-text/long-text.component'; import { SelectRowComponent } from '../../ui-components/row-fields/select/select.component'; import { UiSettingsService } from 'src/app/services/ui-settings.service'; +import { CompanyService } from 'src/app/services/company.service'; @Component({ selector: 'app-db-table-widgets', @@ -175,6 +176,7 @@ export class DbTableWidgetsComponent implements OnInit { private _tables: TablesService, private _location: Location, private _uiSettings: UiSettingsService, + private _company: CompanyService, public dialog: MatDialog, public router: Router, private title: Title, @@ -194,7 +196,7 @@ export class DbTableWidgetsComponent implements OnInit { this.fieldsCount = res.structure.length; this.fields = res.structure.map((field: TableField) => field.column_name); this.dispalyTableName = res.display_name || normalizeTableName(this.tableName); - this.title.setTitle(`${this.dispalyTableName} - Field display | Rocketadmin`); + this.title.setTitle(`${this.dispalyTableName} - Field display | ${this._company.companyTabTitle || 'Rocketadmin'}`); this.getWidgets(); }) this.codeEditorTheme = this._uiSettings.editorTheme; diff --git a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts index 610bcae07..17601ced2 100644 --- a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts +++ b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts @@ -38,6 +38,7 @@ import { Title } from '@angular/platform-browser'; import { getTableTypes } from 'src/app/lib/setup-table-row-structure'; import { normalizeTableName } from '../../lib/normalize'; import { MatProgressSpinnerModule, MatSpinner } from '@angular/material/progress-spinner'; +import { CompanyService } from 'src/app/services/company.service'; @Component({ selector: 'app-db-table-row-edit', @@ -118,6 +119,7 @@ export class DbTableRowEditComponent implements OnInit { private _tableRow: TableRowService, private _notifications: NotificationsService, private _tableState: TableStateService, + private _company: CompanyService, private route: ActivatedRoute, private ngZone: NgZone, public router: Router, @@ -149,7 +151,7 @@ export class DbTableRowEditComponent implements OnInit { this._tables.fetchTableStructure(this.connectionID, this.tableName) .subscribe(res => { this.dispalyTableName = res.display_name || normalizeTableName(this.tableName); - this.title.setTitle(`${this.dispalyTableName} - Add new record | Rocketadmin`); + this.title.setTitle(`${this.dispalyTableName} - Add new record | ${this._company.companyTabTitle || 'Rocketadmin'}`); this.permissions = { visibility: true, readonly: false, diff --git a/frontend/src/app/components/user-settings/user-settings.component.ts b/frontend/src/app/components/user-settings/user-settings.component.ts index 51dbb517e..c2661898a 100644 --- a/frontend/src/app/components/user-settings/user-settings.component.ts +++ b/frontend/src/app/components/user-settings/user-settings.component.ts @@ -24,6 +24,8 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { NotificationsService } from 'src/app/services/notifications.service'; import { RouterModule } from '@angular/router'; import { UserService } from 'src/app/services/user.service'; +import { CompanyService } from 'src/app/services/company.service'; +import { Title } from '@angular/platform-browser'; @Component({ selector: 'app-user-settings', @@ -83,11 +85,14 @@ export class UserSettingsComponent implements OnInit { private _userService: UserService, private _authService: AuthService, private _notifications: NotificationsService, + private _company: CompanyService, public dialog: MatDialog, + private title: Title, private angulartics2: Angulartics2, ) {} ngOnInit(): void { + this.title.setTitle(`Account settings | ${this._company.companyTabTitle || 'Rocketadmin'}`); this.currentUser = null; this._userService.cast .subscribe(user => { diff --git a/frontend/src/app/components/users/users.component.ts b/frontend/src/app/components/users/users.component.ts index 9b8ac4563..26b502aba 100644 --- a/frontend/src/app/components/users/users.component.ts +++ b/frontend/src/app/components/users/users.component.ts @@ -72,7 +72,7 @@ export class UsersComponent implements OnInit, OnDestroy { ngOnInit() { this.getTitleSubscription = this._connections.getCurrentConnectionTitle().subscribe(connectionTitle => { - this.title.setTitle(`User permissions - ${connectionTitle} | Rocketadmin`); + this.title.setTitle(`User permissions - ${connectionTitle} | ${this._company.companyTabTitle || 'Rocketadmin'}`); }); this.connectionID = this._connections.currentConnectionID; this.getUsersGroups(); From 366d782c73b1a25aad9f0433ae01040854423442 Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 13 Apr 2025 12:31:17 +0300 Subject: [PATCH 3/4] white label: fix tab title delete --- frontend/src/app/components/company/company.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/components/company/company.component.html b/frontend/src/app/components/company/company.component.html index 30a3b9aca..010119336 100644 --- a/frontend/src/app/components/company/company.component.html +++ b/frontend/src/app/components/company/company.component.html @@ -314,7 +314,7 @@

White label

From 4028d52a385bd115264ac01931a0a63573ecc124 Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 13 Apr 2025 13:26:02 +0300 Subject: [PATCH 4/4] white label: fix unit tests --- frontend/src/app/app.component.spec.ts | 2 ++ .../components/company/company.component.spec.ts | 1 + .../assets/{custom-domain.gif => custom_domain.gif} | Bin 3 files changed, 3 insertions(+) rename frontend/src/assets/{custom-domain.gif => custom_domain.gif} (100%) diff --git a/frontend/src/app/app.component.spec.ts b/frontend/src/app/app.component.spec.ts index 391d76b3e..d175be3d5 100644 --- a/frontend/src/app/app.component.spec.ts +++ b/frontend/src/app/app.component.spec.ts @@ -244,6 +244,8 @@ describe('AppComponent', () => { }); it('should handle user login flow when cast emits user with expires', fakeAsync(() => { + mockCompanyService.getWhiteLabelProperties.and.returnValue(of({logo: '', favicon: ''})); + const expirationDate = new Date(Date.now() + 10_000); // 10s from now app['currentFeatureNotificationId'] = 'some-id'; diff --git a/frontend/src/app/components/company/company.component.spec.ts b/frontend/src/app/components/company/company.component.spec.ts index ea95f69c9..2e351f251 100644 --- a/frontend/src/app/components/company/company.component.spec.ts +++ b/frontend/src/app/components/company/company.component.spec.ts @@ -113,6 +113,7 @@ describe('CompanyComponent', () => { fakeCompanyService.getCustomDomain.and.returnValue(of(mockCompanyDomain)); fakeCompanyService.updateCompanyName.and.returnValue(of({})); fakeCompanyService.updateCompanyMemberRole.and.returnValue(of({})); + fakeCompanyService.getCurrentTabTitle = jasmine.createSpy().and.returnValue(of('Rocketadmin')); fakeUserService.cast = of(mockMembers[1]); beforeEach(async () => { diff --git a/frontend/src/assets/custom-domain.gif b/frontend/src/assets/custom_domain.gif similarity index 100% rename from frontend/src/assets/custom-domain.gif rename to frontend/src/assets/custom_domain.gif