Skip to content

Commit

Permalink
Merge pull request #260 from amosproj/refactor/xd-243
Browse files Browse the repository at this point in the history
Refactor/xd 243
  • Loading branch information
IngoSternberg authored Jul 16, 2024
2 parents 791276e + c193a8c commit 5006322
Show file tree
Hide file tree
Showing 102 changed files with 1,449 additions and 1,397 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ INSIGHT_HUB_API_KEY=KEY

# Frontend
XD_API_URL=http://${BACKEND_HOST}:${BACKEND_PORT}
SECRET_KEY=SecretKey
SECRET_KEY=askIngo

# Swagger
# Just the subpath of the URL where the Swagger UI will be available
Expand Down
6 changes: 1 addition & 5 deletions apps/frontend/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Component, inject } from '@angular/core';
// import { provideAnimations } from '@angular/platform-browser/animations';
import { Component } from '@angular/core';
import { RouterModule } from '@angular/router';
import { APP_CONFIG } from 'common-frontend-models';
import { NgxEchartsDirective } from 'ngx-echarts';

@Component({
Expand All @@ -12,6 +10,4 @@ import { NgxEchartsDirective } from 'ngx-echarts';
styleUrl: './app.component.scss',
})
export class AppComponent {
title = 'frontend';
readonly apiUrl = inject(APP_CONFIG).apiUrl;
}
4 changes: 2 additions & 2 deletions apps/frontend/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const APP_ROUTES: Route[] = [
path: '',
canActivate: [ AuthenticationGuard ],
loadComponent: () =>
import('./pages/home/home.component').then((m) => m.HomeComponent),
import('./pages/home/home.page').then((m) => m.HomePage),
},
{
path: 'home',
Expand Down Expand Up @@ -53,7 +53,7 @@ export const APP_ROUTES: Route[] = [
path: 'not-found',
canActivate: [ AuthenticationGuard ],
loadComponent: () =>
import('./pages/not-found/not-found.component').then((m) => m.NotFoundComponent),
import('./pages/not-found/not-found.page').then((m) => m.NotFoundPage),
},
{
path: 'account',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
</ix-breadcrumb>

@if (!isHomePage()){
<div class="absolute top-10 right-4 !z-[50] flex flex-row-reverse gap-x-4">
<ix-button icon="refresh" (click)="refresh()">Refresh</ix-button>
</div>
<ix-button class="absolute top-10 right-4" icon="refresh" (click)="refresh()">Refresh</ix-button>
}

<ix-menu>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('HeaderComponent', () => {
} as unknown as LocalStorageService;

authenticationServiceMock = {
getUserMail: jest.fn().mockReturnValue('[email protected]'),
getUserEmail: jest.fn().mockReturnValue('[email protected]'),
logout: jest.fn()
} as unknown as AuthenticationService;

Expand All @@ -76,21 +76,21 @@ describe('HeaderComponent', () => {
it('should trigger router events correctly', () => {
eventsSubject.next(new NavigationEnd(1, '', ''));

const routerEvents = component.routerEvents();
const routerEvents = component['routerEvents']();
expect(routerEvents).toBeInstanceOf(NavigationEnd);
});

it('should compute breadcrumbs correctly', () => {
eventsSubject.next(new NavigationEnd(1, '', ''));

const breadcrumbs = component.breadcrumbs();
const breadcrumbs = component['breadcrumbs']();
expect(breadcrumbs).toEqual([ 'Layer 1', 'Layer 2' ]);
});

it('should determine if it is home page correctly', () => {
eventsSubject.next(new NavigationEnd(1, '', ''));

const isHomePage = component.isHomePage();
const isHomePage = component['isHomePage']();
expect(isHomePage).toBe(true);
});

Expand Down
15 changes: 8 additions & 7 deletions apps/frontend/src/app/components/header/header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,20 @@ import { LegalInformationComponent } from './legal-information/legal-information
})
export class HeaderComponent {

protected lightMode = computed(() => {
protected readonly userMail = this._authenticationService.getUserEmail();

protected readonly lightMode = computed(() => {
const theme = this._localStorageService.getOrCreate('theme', 'theme-classic-dark')();
themeSwitcher.setTheme(theme);
return theme === 'theme-classic-light';
});
protected userMail = this.authenticationService.getUserMail();

readonly routerEvents = toSignal(
private readonly routerEvents = toSignal(
this._router.events.pipe(filter((e) => e instanceof NavigationEnd)),
{ initialValue: null },
);

readonly breadcrumbs = computed(() => {
protected readonly breadcrumbs = computed(() => {
this.routerEvents();

const breadcrumbs = [];
Expand All @@ -59,13 +60,13 @@ export class HeaderComponent {
return breadcrumbs;
});

readonly isHomePage = computed(() => {
protected readonly isHomePage = computed(() => {
this.routerEvents();
return this._activatedRoute.snapshot.firstChild?.routeConfig?.path === '';
});

constructor(
protected authenticationService: AuthenticationService,
private _authenticationService: AuthenticationService,
private _localStorageService: LocalStorageService,
private _router: Router,
private _activatedRoute: ActivatedRoute,
Expand All @@ -92,7 +93,7 @@ export class HeaderComponent {
}

logout(){
this.authenticationService.logout();
this._authenticationService.logout();
this._router.navigate([ '/account/login' ]);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';

import { HomeComponent } from './home.component';
import { HomePage } from './home.page';

describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
let component: HomePage;
let fixture: ComponentFixture<HomePage>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ HomeComponent ],
imports: [ HomePage ],
providers: [
{
provide: ActivatedRoute,
Expand All @@ -18,7 +18,7 @@ describe('HomeComponent', () => {
],
}).compileComponents();

fixture = TestBed.createComponent(HomeComponent);
fixture = TestBed.createComponent(HomePage);
component = fixture.componentInstance;
fixture.detectChanges();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { IxModule } from '@siemens/ix-angular';
selector: 'app-home',
standalone: true,
imports: [ CommonModule, IxModule, RouterLink, NgOptimizedImage ],
templateUrl: './home.component.html',
styleUrl: './home.component.scss',
templateUrl: './home.page.html',
styleUrl: './home.page.scss',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HomeComponent {}
export class HomePage {}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';

import { NotFoundComponent } from './not-found.component';
import { NotFoundPage } from './not-found.page';

describe('NotFoundComponent', () => {
let component: NotFoundComponent;
let fixture: ComponentFixture<NotFoundComponent>;
let component: NotFoundPage;
let fixture: ComponentFixture<NotFoundPage>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ NotFoundComponent ],
imports: [ NotFoundPage ],
providers: [
{
provide: ActivatedRoute,
Expand All @@ -18,7 +18,7 @@ describe('NotFoundComponent', () => {
],
}).compileComponents();

fixture = TestBed.createComponent(NotFoundComponent);
fixture = TestBed.createComponent(NotFoundPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { IxModule } from '@siemens/ix-angular';
selector: 'app-not-found',
standalone: true,
imports: [ CommonModule, IxModule, RouterLink ],
templateUrl: './not-found.component.html',
styleUrl: './not-found.component.scss',
templateUrl: './not-found.page.html',
styleUrl: './not-found.page.scss',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'app-not-found',
},
})
export class NotFoundComponent {}
export class NotFoundPage {}
Binary file removed apps/frontend/src/assets/Xcelerator.jpg
Binary file not shown.
Binary file removed apps/frontend/src/assets/diagram.png
Binary file not shown.
4 changes: 2 additions & 2 deletions apps/frontend/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

@import '@siemens/ix/dist/siemens-ix/siemens-ix.css';

.test-custom-class {
@apply bg-red-500 rounded text-center;
.top-right-button {
@apply absolute top-20 right-4;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="absolute top-1/3 left-1/2 -translate-x-1/2 -translate-y-1/3">

<form
class="needs-validation w-96 bg-[#283236] px-6 py-9"
class="needs-validation w-96 tile-color px-6 py-9"
[ngClass]="{ 'was-validated': wasValidated }"
(submit)="onSubmit()"
>
Expand Down Expand Up @@ -29,7 +29,7 @@
class="pl-2"
name="password"
placeholder="Enter password"
type="password"
[type]="showPassword ? 'text' : 'password'"
[(ngModel)]="password"
required
>
Expand All @@ -42,9 +42,9 @@
<div class="pt-10">
@if (formValid()) {
@if (loginSuccess()) {
<div class="text-[#3dbe0c] pb-2">Login success!</div>
<div class="text-success pb-2">Login success!</div>
} @else {
<div class="text-[#f9526c] pb-2">Invalid email address or password!</div>
<div class="text-danger pb-2">Invalid email address or password!</div>
}
}
<button class="btn btn-primary w-full" type="submit">Login</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.tile-color {
background-color: var(--theme-color-1--hover);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Router } from '@angular/router';
import { AuthenticationService } from 'common-frontend-models';
import { of } from 'rxjs';

import { LoginPage } from './login.page';

Expand All @@ -13,7 +12,8 @@ describe('LoginPage', () => {

beforeEach(async () => {
authServiceMock = {
login: jest.fn().mockReturnValue(of(true)),
login: jest.fn().mockReturnValue(true),
isLoggedIn: jest.fn().mockReturnValue(false),
} as unknown as jest.Mocked<AuthenticationService>;

routerMock = {
Expand All @@ -39,16 +39,17 @@ describe('LoginPage', () => {

describe('onSubmit', () => {
it('should not validate form if email or password is invalid', () => {
component.email = 'invalid-email';
component.password = '';
// bypass protected attribute using bracket notation
component['email'] = 'invalid-email';
component['password'] = '';
component.onSubmit();

expect(routerMock.navigate).not.toHaveBeenCalled();
});

it('should validate form and login successfully', () => {
component.email = '[email protected]';
component.password = 'password';
component['email']= '[email protected]';
component['password'] = 'password';
component.onSubmit();

expect(routerMock.navigate).toHaveBeenCalledWith([ '/' ]);
Expand Down
42 changes: 19 additions & 23 deletions libs/account/frontend/view/src/lib/components/login/login.page.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,46 @@
import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, signal, ViewEncapsulation } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnInit, signal, ViewEncapsulation } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { IxModule, themeSwitcher } from '@siemens/ix-angular';
import { IxModule } from '@siemens/ix-angular';
import { AuthenticationService } from 'common-frontend-models';

@Component({
selector: 'lib-login',
selector: 'lib-account-login',
standalone: true,
imports: [ CommonModule, FormsModule, IxModule ],
templateUrl: './login.page.html',
styleUrls: [ './login.page.scss' ],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LoginPage {
public email = '';
public password = '';
export class LoginPage implements OnInit {
protected email = '';
protected password = '';

protected formValid = signal(false);
protected loginSuccess = signal(false);
protected wasValidated = false;
protected showPassword = false;

private readonly emailRegExp = /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
private readonly _emailPattern = /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;

protected readonly formValid = signal(false);
protected readonly loginSuccess = signal(false);

constructor(
private _router: Router,
private _authenticationService: AuthenticationService,
) {
// this site is always in dark mode
themeSwitcher.setTheme('theme-classic-dark');
}
private readonly _router: Router,
private readonly _authenticationService: AuthenticationService,
) {}

ngOnInit(){
if(this._authenticationService.isLoggedIn()){
this._router.navigate([ '/' ]);
}
}

onSubmit() {
this.wasValidated = true;

const formValid = this.emailRegExp.test(this.email) && this.password !== '';
const formValid = this._emailPattern.test(this.email) && this.password !== '';
this.formValid.set(formValid);
if(!formValid){
return;
Expand All @@ -52,14 +55,7 @@ export class LoginPage {
}

togglePassword() {
const passwordElement = document.getElementById('passwordElement');
if(!passwordElement) {
return;
}

this.showPassword = !this.showPassword;
const typeVal = this.showPassword ? 'text' : 'password';
passwordElement.setAttribute('type', typeVal);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ describe('CaseController', () => {
title: faker.lorem.sentence(),
type: faker.helpers.enumValue(ECaseType),
status: faker.helpers.enumValue(ECaseStatus),
assignedTo: faker.internet.email(),
description: faker.lorem.sentence(),
source: faker.string.alpha(),
priority: faker.helpers.enumValue(ECasePriority),
Expand Down
Loading

0 comments on commit 5006322

Please sign in to comment.