Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions frontend/src/app/app.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@
color: #fff;
}

.logo-box {
display: flex;
align-items: center;
}

.logo {
display: flex;
align-items: center;
Expand All @@ -123,6 +128,14 @@
margin-right: 12px;
}

.logo__demo-mark {
background: var(--color-accentedPalette-700);
font-size: 12px;
line-height: 20px;
margin-bottom: -2px;
padding: 0 8px;
}

.menu {
display: flex;
align-items: center;
Expand Down
13 changes: 11 additions & 2 deletions frontend/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<img src="../assets/rocketadmin_logo_white.svg" *ngIf="whiteLabelSettings.logo !== '' && !whiteLabelSettings.logo" class="logo__image">
</a>-->

<div>
<div class="logo-box">
<a routerLink="/connections-list"
*ngIf="userLoggedIn"
class="logo">
Expand All @@ -81,6 +81,7 @@
<img src="../assets/rocketadmin_logo_white.svg" alt="Rocketadmin logo" class="logo__image">
</picture>
</a>
<span *ngIf="isDemo" class="logo__demo-mark">demo</span>
</div>

<div *ngIf="connectionID" class="menu">
Expand Down Expand Up @@ -108,13 +109,21 @@
</button>

<div *ngIf="userLoggedIn === true" class="actions actions_auth">
<a routerLink="/upgrade" *ngIf="isSaas && currentUser && currentUser.role === 'ADMIN'"
<a routerLink="/upgrade" *ngIf="isSaas && currentUser && currentUser.role === 'ADMIN' && !isDemo"
mat-flat-button color="accent"
data-testid="upgrade-header-link"
class="nav-bar__upgrade-button">
Upgrade
</a>

<button type="button" *ngIf="isSaas && currentUser && currentUser.role === 'ADMIN' && isDemo"
mat-flat-button color="accent"
data-testid="upgrade-header-link"
class="nav-bar__upgrade-button"
(click)="logoutAndRedirectToRegistration()">
Create account
</button>

<button mat-icon-button type="button" data-testid="account-menu-anchor-header-button"
matBadge="1" [matBadgeHidden]="currentUser.isActive"
matBadgeColor="accent" matBadgeSize="small"
Expand Down
25 changes: 13 additions & 12 deletions frontend/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { Subject, of } from 'rxjs';

import { Angulartics2Module } from 'angulartics2';
import { AppComponent } from './app.component';
import { AuthService } from './services/auth.service';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { By } from '@angular/platform-browser';
import { ChangeDetectorRef } from '@angular/core';
import { CompanyService } from './services/company.service';
import { ConnectionsService } from './services/connections.service';
// import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { MatDialogModule } from '@angular/material/dialog';
import { MatMenuModule } from '@angular/material/menu';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { RouterTestingModule } from '@angular/router/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { provideHttpClient } from '@angular/common/http';
import { of, Subject } from 'rxjs';
import { AuthService } from './services/auth.service';
import { UserService } from './services/user.service';
import { CompanyService } from './services/company.service';
import { UiSettingsService } from './services/ui-settings.service';
import { TablesService } from './services/tables.service';
// import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { ChangeDetectorRef } from '@angular/core';
import { UiSettingsService } from './services/ui-settings.service';
import { UserService } from './services/user.service';
import { provideHttpClient } from '@angular/common/http';

describe('AppComponent', () => {
let app: AppComponent;
Expand Down Expand Up @@ -52,7 +52,8 @@ describe('AppComponent', () => {

const mockUserService = {
cast: userCast,
fetchUser: jasmine.createSpy('fetchUser').and.returnValue(of(fakeUser))
fetchUser: jasmine.createSpy('fetchUser').and.returnValue(of(fakeUser)),
setIsDemo: jasmine.createSpy('setIsDemo'),
};

const mockCompanyService = {
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class AppComponent {
isFeatureNotificationShown: boolean = false;

userLoggedIn = null;
isDemo = false;
redirect_uri = `${location.origin}/loader`;
connections = [];
token = null;
Expand Down Expand Up @@ -223,6 +224,8 @@ export class AppComponent {
this._user.fetchUser()
.subscribe((res: User) => {
this.currentUser = res;
this.isDemo = this.currentUser.email.startsWith('demo_') && this.currentUser.email.endsWith('@rocketadmin.com');
this._user.setIsDemo(this.isDemo);
this.setUserLoggedIn(true);
// @ts-ignore
if (typeof window.Intercom !== 'undefined') window.Intercom("boot", {
Expand Down Expand Up @@ -285,6 +288,19 @@ export class AppComponent {
this.changeDetector.detectChanges();
}

logoutAndRedirectToRegistration() {
this._auth.logOutUser().subscribe(() => {
this.setUserLoggedIn(false);
this.isDemo = false;
this._user.setIsDemo(false);
this.currentUser = null;
localStorage.removeItem('token_expiration');
this.router.navigate(['/registration']);
}
);

}

logOut(isTokenExpired?: boolean) {
try {
// @ts-ignore
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/components/company/company.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ <h2 class="heading-2 tableHeader__heading">Branding</h2>

<div class="white-label">
<div class="white-label-settings">
<div *ngIf="(currentPlan === 'free' || currentUser.role === 'DB_ADMIN') && isSaas"
<div *ngIf="(currentPlan === 'free' || currentUser.role === 'DB_ADMIN') && isSaas && !isDemo"
class="white-label-settings__overlay"
[matTooltip]="currentUser.role === 'DB_ADMIN' ? 'Contact your Account Owner to set up white label settings.' : 'To white‑label your domain, please upgrade to the Team plan or higher.'">
</div>
Expand Down Expand Up @@ -476,7 +476,7 @@ <h3>Configure DNS Records</h3>
data-testid="company-test-connections-switch"
[(ngModel)]="company.show_test_connections"
(change)="changeShowTestConnections($event.checked)">
Show demo connections
Show demo admin panels
</mat-slide-toggle>
</div>

4 changes: 4 additions & 0 deletions frontend/src/app/components/company/company.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ export class CompanyComponent {
return this._company.whiteLabelSettings || { logo: '', favicon: '', tabTitle : '' };
}

get isDemo() {
return this._user.isDemo;
}

private getTitleSubscription: Subscription;

constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<app-alert></app-alert>
<app-alert *ngIf="isDemo" [alert]="isDemoConnectionWarning"></app-alert>

<div class="connectPage">
<form action="" #connectForm="ngForm" class="form"
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/app/components/connect-db/connect-db.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ export class ConnectDBComponent implements OnInit {

private getTitleSubscription: Subscription;

// public isDemo: boolean = false;

public isDemoConnectionWarning: Alert = {
id: 10000000,
type: AlertType.Warning,
message: 'This is a DEMO SESSION! It will disappear after you log out. Don\'t use databases you\'re actively using or that contain information you wish to retain.'
}

constructor(
private _connections: ConnectionsService,
private _notifications: NotificationsService,
Expand All @@ -112,6 +120,10 @@ export class ConnectDBComponent implements OnInit {
private title: Title
) { }

get isDemo() {
return this._user.isDemo;
}

ngOnInit() {
this.connectionID = this._connections.currentConnectionID;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
}

.addButton {
margin-top: 12px;
margin-top: -44px;
height: 40px;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ <h2 class="connectionInfo__connectionTitle">{{ titles[connectionItem.connection.
Show less
</button>

<div [ngClass]="connections.length ? 'fabActions' : null">
<a routerLink="/zapier" *ngIf="connections.length" class="zapier-link">
<div class="fabActions">
<a routerLink="/zapier" class="zapier-link">
<svg class="zapier-link__logo" width="401" height="400" viewBox="0 0 401 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.526367" width="400" height="400" fill="#FF4F00"/>
<rect x="0.526367" width="400" height="400" rx="200" fill="#FF4F00"/>
Expand All @@ -213,21 +213,30 @@ <h2 class="connectionInfo__connectionTitle">{{ titles[connectionItem.connection.
</svg>
</a>

<a mat-flat-button *ngIf="currentUser.role === 'ADMIN' || currentUser.role === 'DB_ADMIN'"
<a mat-flat-button *ngIf="(currentUser.role === 'ADMIN' || currentUser.role === 'DB_ADMIN') && connections?.length"
data-testid="add-connection-button"
color="primary"
[ngClass]="connections.length ? 'fabAddButton' : 'addButton'"
class="fabAddButton"
routerLink="/connect-db"
angulartics2On="click"
angularticsAction="Connections: Add connection button is clicked">
<mat-icon *ngIf="connections?.length">add</mat-icon>
Add database
</a>
</div>
<a mat-flat-button *ngIf="(currentUser.role === 'ADMIN' || currentUser.role === 'DB_ADMIN') && !connections?.length"
data-testid="add-connection-button"
color="primary"
class="addButton"
routerLink="/connect-db"
angulartics2On="click"
angularticsAction="Connections: Add connection button is clicked">
<mat-icon *ngIf="connections?.length">add</mat-icon>
Add database
</a>



<div *ngIf="!connections.length && connections !== null" class="empty-state_bottom">
<div *ngIf="!connections.length && connections !== null && !isDemo" class="empty-state_bottom">
<p class="mat-body-1 empty-state__text">
Invited to the company and don't see admin panel?
</p>
Expand All @@ -239,7 +248,7 @@ <h2 class="connectionInfo__connectionTitle">{{ titles[connectionItem.connection.
<mat-divider *ngIf="testConnections && testConnections.length" class="connections-divider"></mat-divider>

<ng-container *ngIf="testConnections && testConnections.length">
<h1 class="mat-display-1">Demo Admin Panels</h1>
<h1 class="mat-display-1">Explore demo admin panels</h1>

<ul class="testConnections">
<li *ngFor="let testConnectionItem of testConnections">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ export class ConnectionsListComponent implements OnInit {
private title: Title
) { }

get isDemo() {
return this._userService.isDemo;
}

ngOnInit(): void {
this._companyService.getCurrentTabTitle()
.pipe(take(1))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<app-alert></app-alert>
<app-alert *ngIf="currentUser.id && !currentUser.isActive" [alert]="emailVerificationWarning"></app-alert>
<app-alert *ngIf="currentUser.id && !currentUser.isActive && !isDemo" [alert]="emailVerificationWarning"></app-alert>
<app-alert *ngIf="currentUser.id && isDemo" [alert]="isDemoAccountWarning"></app-alert>

<div class="page">
<h1 class="mat-h1">
Expand Down Expand Up @@ -91,7 +92,7 @@ <h1 class="mat-h1">
[disabled]="submittingChangedShowTestConnections"
[(ngModel)]="showTestConnections"
(change)="changeShowTestConnections($event.checked)">
Show demo connections
Show demo admin panels
</mat-slide-toggle>

<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Alert, AlertActionType, AlertType } from 'src/app/models/alert';
import { Angulartics2, Angulartics2OnModule } from 'angulartics2';
import { ApiKey, User } from 'src/app/models/user';
import { Component, Input, OnInit } from '@angular/core';

import { AccountDeleteDialogComponent } from './account-delete-dialog/account-delete-dialog.component';
import { AlertComponent } from '../ui-components/alert/alert.component';
import { Angulartics2, Angulartics2OnModule } from 'angulartics2';
import { Angulartics2Module } from 'angulartics2';
import { ApiKeyDeleteDialogComponent } from './api-key-delete-dialog/api-key-delete-dialog.component';
import { AuthService } from 'src/app/services/auth.service';
import { CdkCopyToClipboard } from '@angular/cdk/clipboard';
import { CommonModule } from '@angular/common';
import { CompanyService } from 'src/app/services/company.service';
import { EnableTwoFADialogComponent } from './enable-two-fa-dialog/enable-two-fa-dialog.component';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
Expand All @@ -23,9 +24,8 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
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';
import { UserService } from 'src/app/services/user.service';

@Component({
selector: 'app-user-settings',
Expand Down Expand Up @@ -81,6 +81,12 @@ export class UserSettingsComponent implements OnInit {
public generatingAPIkeyTitle: string;
public generatedAPIkeyHash: string;

public isDemoAccountWarning: Alert = {
id: 10000000,
type: AlertType.Warning,
message: 'This is a DEMO SESSION! Once you log out, all changes made will be lost.',
}

constructor(
private _userService: UserService,
private _authService: AuthService,
Expand All @@ -91,6 +97,10 @@ export class UserSettingsComponent implements OnInit {
private angulartics2: Angulartics2,
) {}

get isDemo() {
return this._userService.isDemo;
}

ngOnInit(): void {
this.title.setTitle(`Account settings | ${this._company.companyTabTitle || 'Rocketadmin'}`);
this.currentUser = null;
Expand Down
1 change: 1 addition & 0 deletions frontend/src/app/components/users/users.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Alert, AlertType } from 'src/app/models/alert';
import { CommonModule, NgClass, NgForOf, NgIf } from '@angular/common';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { GroupUser, User, UserGroup, UserGroupInfo } from 'src/app/models/user';
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/app/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export class UserService {
}
}

public isDemoEmail: boolean = false;

private user = new BehaviorSubject<any>(this.initialUserState);
public cast = this.user.asObservable();

Expand All @@ -41,6 +43,14 @@ export class UserService {
return this.user.asObservable();
}

setIsDemo(isDemo: boolean) {
this.isDemoEmail = isDemo;
}

get isDemo() {
return this.isDemoEmail
}

fetchUser() {
return this._http.get<any>('/user')
.pipe(
Expand Down