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
26 changes: 25 additions & 1 deletion frontend/src/app/app.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@
}
}

.nav-bar__button {
.nav-bar__slash {
color: #fff;
margin-bottom: -4px;
}

.nav-bar__button{
--mdc-text-button-label-text-color: rgba(255, 255, 255, 1) !important;
--mat-mdc-button-persistent-ripple-color: transparent !important;

Expand All @@ -64,12 +69,21 @@
transition: outline 0.2s;
}

.nav-bar__button[disabled="true"] {
--mdc-text-button-disabled-label-text-color: #fff;
}


@media (prefers-color-scheme: dark) {
.nav-bar__button {
color: #fff;
}
}

.nav-bar__buttonConnectionsMenu {
margin-bottom: -4px;
}

.nav-bar__account-button ::ng-deep .mat-badge-content {
top: 14px;
left: 32px;
Expand Down Expand Up @@ -136,6 +150,16 @@
padding: 0 8px;
}

.connection_active {
background: var(--color-accentedPalette-100);
}

@media (prefers-color-scheme: dark) {
.connection_active {
background: var(--color-accentedPalette-800);
}
}

.menu {
display: flex;
align-items: center;
Expand Down
33 changes: 26 additions & 7 deletions frontend/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,36 @@
<img src="../assets/rocketadmin_logo_white.svg" alt="Rocketadmin logo" class="logo__image">
</picture>
</a>
<span *ngIf="connectionID" class="nav-bar__slash">/</span>
<button *ngIf="connectionID"
mat-button type="button" class="nav-bar__button nav-bar__buttonConnectionsMenu"
[disabled]="ownUserConnections && ownUserConnections.length === 1 && !isTestConnection"
[matMenuTriggerFor]="connectionsListMenu">
{{currentConnectionName}}
<mat-icon iconPositionEnd
*ngIf="ownUserConnections && ownUserConnections.length !== 1 || isTestConnection"
style="margin-left: 4px">
arrow_drop_down
</mat-icon>
</button>
<mat-menu #connectionsListMenu="matMenu">
<a *ngIf="ownUserConnections && ownUserConnections.length === 0; else connectionsList"
mat-menu-item
routerLink="/connect-db">
Add your own connection
</a>
<ng-template #connectionsList>
<a mat-menu-item *ngFor="let connection of ownUserConnections"
routerLink="/dashboard/{{connection.connection.id}}"
[ngClass]="{'connection_active': connectionID === connection.connection.id}">
{{connection.displayTitle}}
</a>
</ng-template>
</mat-menu>
<span *ngIf="isDemo" class="logo__demo-mark">demo</span>
</div>

<div *ngIf="connectionID" class="menu">
<a mat-button data-testid="connections-list-header-link"
routerLink="/connections-list"
routerLinkActive="nav-bar__button_active"
class="nav-bar__button">
Connections
</a>
<mat-icon class="nav-bar__button">chevron_right</mat-icon>
<a mat-button *ngFor="let tab of visibleTabs" attr.data-testid="{{tab}}-header-link"
routerLink="{{tab}}/{{connectionID}}"
routerLinkActive="nav-bar__button_active"
Expand Down
20 changes: 14 additions & 6 deletions frontend/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,22 @@ describe('AppComponent', () => {
};

const mockUiSettingsService = {
getUiSettings: jasmine.createSpy('getUiSettings'),
updateGlobalSetting: jasmine.createSpy('updateGlobalSetting')
getUiSettings: jasmine.createSpy('getUiSettings').and.returnValue(of({globalSettings: {lastFeatureNotificationId: 'default-id'}})),
updateGlobalSetting: jasmine.createSpy('updateGlobalSetting').and.returnValue(of({}))
};

const connectionsCast = new Subject<any>();

const mockConnectionsService = {
isCustomAccentedColor: true,
connectionID: '123',
visibleTabs: ['dashboard'],
currentTab: 'dashboard'
currentTab: 'dashboard',
currentConnection: {
isTestConnection: false
},
cast: connectionsCast,
fetchConnections: jasmine.createSpy('fetchConnections').and.returnValue(of([]))
};

const mockTablesService = {
Expand Down Expand Up @@ -139,7 +146,7 @@ describe('AppComponent', () => {

it('should set userLoggedIn and logo on user session initialization', fakeAsync(() => {
mockCompanyService.getWhiteLabelProperties.and.returnValue(of({logo: 'data:png;base64,some-base64-data'}));
mockUiSettingsService.getUiSettings.and.returnValue(of({settings: {globalSettings: {lastFeatureNotificationId: 'old-id'}}}));
mockUiSettingsService.getUiSettings.and.returnValue(of({globalSettings: {lastFeatureNotificationId: 'old-id'}}));
app.initializeUserSession();
tick();

Expand All @@ -151,7 +158,7 @@ describe('AppComponent', () => {

it('should render custom logo in navbar if it is set', fakeAsync(() => {
mockCompanyService.getWhiteLabelProperties.and.returnValue(of({logo: 'data:png;base64,some-base64-data'}));
mockUiSettingsService.getUiSettings.and.returnValue(of({settings: {globalSettings: {lastFeatureNotificationId: 'old-id'}}}));
mockUiSettingsService.getUiSettings.and.returnValue(of({globalSettings: {lastFeatureNotificationId: 'old-id'}}));
app.initializeUserSession();
tick();

Expand All @@ -165,7 +172,7 @@ describe('AppComponent', () => {

it('should render the link to Connetions list that contains the custom logo in the navbar', fakeAsync(() => {
mockCompanyService.getWhiteLabelProperties.and.returnValue(of({logo: null}));
mockUiSettingsService.getUiSettings.and.returnValue(of({settings: {globalSettings: {lastFeatureNotificationId: 'old-id'}}}));
mockUiSettingsService.getUiSettings.and.returnValue(of({globalSettings: {lastFeatureNotificationId: 'old-id'}}));
app.initializeUserSession();
tick();

Expand Down Expand Up @@ -246,6 +253,7 @@ describe('AppComponent', () => {

it('should handle user login flow when cast emits user with expires', fakeAsync(() => {
mockCompanyService.getWhiteLabelProperties.and.returnValue(of({logo: '', favicon: ''}));
mockUiSettingsService.getUiSettings.and.returnValue(of({globalSettings: {lastFeatureNotificationId: 'old-id'}}));

const expirationDate = new Date(Date.now() + 10_000); // 10s from now
app['currentFeatureNotificationId'] = 'some-id';
Expand Down
52 changes: 39 additions & 13 deletions frontend/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { catchError, filter, map } from 'rxjs/operators';
import { AuthService } from './services/auth.service';
import { CommonModule } from '@angular/common';
import { CompanyService } from './services/company.service';
import { Connection } from './models/connection';
import { ConnectionsService } from './services/connections.service';
import { DomSanitizer } from '@angular/platform-browser';
import { FeatureNotificationComponent } from './components/feature-notification/feature-notification.component';
Expand Down Expand Up @@ -65,7 +66,6 @@ export class AppComponent {
userLoggedIn = null;
isDemo = false;
redirect_uri = `${location.origin}/loader`;
connections = [];
token = null;
routePathParam;
authBarTheme;
Expand All @@ -81,6 +81,7 @@ export class AppComponent {
logo: '',
favicon: ''
}
public connections: Connection[] = [];

constructor (
private changeDetector: ChangeDetectorRef,
Expand All @@ -98,13 +99,14 @@ export class AppComponent {
private domSanitizer: DomSanitizer,
private matIconRegistry: MatIconRegistry,
) {
this.matIconRegistry.addSvgIcon("mysql", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/mysql_logo.svg"));
this.matIconRegistry.addSvgIcon("mssql", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/mssql_logo.svg"));
this.matIconRegistry.addSvgIcon("oracledb", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/oracle_logo.svg"));
this.matIconRegistry.addSvgIcon("postgres", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/postgres_logo.svg"));
this.matIconRegistry.addSvgIcon("mongodb", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/mongodb_logo.svg"));
this.matIconRegistry.addSvgIcon("dynamodb", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/dynamodb_logo.svg"));
this.matIconRegistry.addSvgIcon("ibmdb2", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/db2.svg"));
this.matIconRegistry.addSvgIcon("mysql", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/db-logos/mysql_logo.svg"));
this.matIconRegistry.addSvgIcon("mssql", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/db-logos/mssql_logo.svg"));
this.matIconRegistry.addSvgIcon("oracledb", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/db-logos/oracle_logo.svg"));
this.matIconRegistry.addSvgIcon("postgres", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/db-logos/postgres_logo.svg"));
this.matIconRegistry.addSvgIcon("mongodb", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/db-logos/mongodb_logo.svg"));
this.matIconRegistry.addSvgIcon("dynamodb", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/db-logos/dynamodb_logo.svg"));
this.matIconRegistry.addSvgIcon("ibmdb2", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/db-logos/db2_logo.svg"));
this.matIconRegistry.addSvgIcon("cassandra", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/db-logos/сassandra_logo.svg"));
this.matIconRegistry.addSvgIcon("github", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/github.svg"));
this.matIconRegistry.addSvgIcon("google", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/google.svg"));
this.matIconRegistry.addSvgIcon("ai_rocket", this.domSanitizer.bypassSecurityTrustResourceUrl("/assets/icons/ai-rocket.svg"));
Expand Down Expand Up @@ -166,12 +168,13 @@ export class AppComponent {
if (!res.isTemporary && res.expires) {
const expirationTime = new Date(res.expires);
if (expirationTime) {
localStorage.setItem('token_expiration', expirationTime.toISOString());
expirationToken = expirationTime.toISOString();
}
localStorage.setItem('token_expiration', expirationTime.toISOString());
expirationToken = expirationTime.toISOString();
}

this.router.navigate(['/connections-list']);

console.log('App component, user logged in, initializing app');
this.initializeUserSession();

const expirationInterval = differenceInMilliseconds(expirationTime, new Date());
Expand All @@ -182,14 +185,15 @@ export class AppComponent {

}
// app initialization if user is logged in (session restoration)
if (expirationToken) {
else if (expirationToken) {
const expirationTime = expirationToken ? new Date(expirationToken) : null;
const currantTime = new Date();

if (expirationTime && currantTime) {
const expirationInterval = differenceInMilliseconds(expirationTime, currantTime);
console.log('expirationInterval', expirationInterval);
if (expirationInterval > 0) {
console.log('App component, session restoration');
this.initializeUserSession();

setTimeout(() => {
Expand Down Expand Up @@ -219,6 +223,14 @@ export class AppComponent {
return this._connections.connectionID;
}

get currentConnectionName() {
return this._connections.currentConnectionName;
}

get isTestConnection() {
return this._connections.currentConnection?.isTestConnection || false;
}

get visibleTabs() {
return this._connections.visibleTabs;
}
Expand All @@ -227,9 +239,13 @@ export class AppComponent {
return this._connections.currentTab;
}

get ownUserConnections() {
return this._connections.ownConnectionsList;
}

initializeUserSession() {
this._user.fetchUser()
.subscribe((res: User) => {
.subscribe((res: User) => {
this.currentUser = res;
this.isDemo = this.currentUser.email.startsWith('demo_') && this.currentUser.email.endsWith('@rocketadmin.com');
this._user.setIsDemo(this.isDemo);
Expand All @@ -247,6 +263,16 @@ export class AppComponent {
if (this.isDemo) window.hj?.('identify', this.currentUser.id, {
'mode': 'demo'
});

// this._connections.fetchConnections()
// .subscribe((res: any) => {
// this.connections = res.filter(connectionItem => !connectionItem.isTestConnection);
// })

this._connections.cast.subscribe( () => {
this._connections.fetchConnections().subscribe();
});

this._company.getWhiteLabelProperties(res.company.id).subscribe( whiteLabelSettings => {
this.whiteLabelSettings.logo = whiteLabelSettings.logo;
this.whiteLabelSettingsLoaded = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ export class ConnectDBComponent implements OnInit {
ngOnInit() {
this.connectionID = this._connections.currentConnectionID;

const databaseType = this.router.routerState.snapshot.root.queryParams.type;

if (databaseType) {
this.db.type = databaseType
this.db.port = this.ports[databaseType];
};

this._connections.getCurrentConnectionTitle()
.pipe(take(1))
.subscribe(connectionTitle => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ <h3 class='mat-subheading-2'>Rocketadmin can not find any tables</h3>
</mat-form-field>
</div>

<mat-form-field appearance="outline">
<!--<mat-form-field appearance="outline">
<mat-label>Project name</mat-label>
<input matInput name="company-name" #username="ngModel"
angulartics2On="change"
angularticsAction="Connection settings: company name is edited"
[disabled]="submitting"
[(ngModel)]="connectionSettings.company_name">
<mat-error *ngIf="username.errors?.required && (username.invalid && username.touched)">Username should not be empty.</mat-error>
</mat-form-field>
</mat-form-field>-->

<div class="color-theme">
<div class="color-item">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
background-position: left 125%, right -26%;
background-size: 17%, 18%;
height: 100%;
padding: 72px max(calc(50vw - 535px), 10%) 24px;
padding: 72px max(calc(50vw - 535px), 10%) 72px;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ <h1 class="mat-headline-4 pageTitle__name" data-testid="company-name">{{companyN
</div>
</ng-template>

<div *ngIf="connections; else loader"
<div *ngIf="ownConnections !== null && testConnections !== null; else loader"
[ngClass]="{'home': !isDemo, 'demoHome': isDemo}">
<app-own-connections
[currentUser]="currentUser"
[connections]="connections"
[connections]="ownConnections"
[isDemo]="isDemo">
</app-own-connections>

Expand Down
Loading