From 6f90661ead35926492bd650c52cf9cb702f9e5bf Mon Sep 17 00:00:00 2001 From: Quentin Monmert Date: Sun, 8 May 2022 19:50:58 +0200 Subject: [PATCH] Angular: refactoring to have a login component --- .../client/angular/core/domain/Angular.java | 6 +- .../security/jwt/domain/AngularJwt.java | 8 +- .../jwt/domain/AngularJwtDomainService.java | 276 ++---------------- .../app/app-routing.module.spec.ts.mustache | 1 + .../app/app-routing.module.ts.mustache | 4 +- .../primary/app/app.component.css.mustache | 22 -- .../primary/app/app.component.html.mustache | 4 +- .../primary/app/app.component.ts.mustache | 2 +- .../common/primary/app/app.module.ts.mustache | 6 +- .../app/login/login.component.css.mustache | 29 ++ .../app/login/login.component.html.mustache | 30 ++ .../login/login.component.spec.ts.mustache | 114 ++++++++ .../app/login/login.component.ts.mustache | 52 ++++ .../webapp/app/login/login.module.ts.mustache | 33 +++ .../webapp/app/login/login.route.ts.mustache | 8 + .../domain/AngularJwtDomainServiceTest.java | 2 +- 16 files changed, 310 insertions(+), 287 deletions(-) create mode 100644 src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.css.mustache create mode 100644 src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.html.mustache create mode 100644 src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.spec.ts.mustache create mode 100644 src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.ts.mustache create mode 100644 src/main/resources/generator/client/angular/src/main/webapp/app/login/login.module.ts.mustache create mode 100644 src/main/resources/generator/client/angular/src/main/webapp/app/login/login.route.ts.mustache diff --git a/src/main/java/tech/jhipster/lite/generator/client/angular/core/domain/Angular.java b/src/main/java/tech/jhipster/lite/generator/client/angular/core/domain/Angular.java index 74c0e32c043..775a46786ce 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/angular/core/domain/Angular.java +++ b/src/main/java/tech/jhipster/lite/generator/client/angular/core/domain/Angular.java @@ -6,6 +6,8 @@ public class Angular { public static final String APP_MODULE = "app.module.ts"; + public static final String APP_ROUTING_MODULE = "app-routing.module.ts"; + public static final String APP_ROUTING_MODULE_SPEC = "app-routing.module.spec.ts"; public static final String APP_COMPONENT = "app.component.ts"; public static final String APP_COMPONENT_SPEC = "app.component.spec.ts"; public static final String APP_COMPONENT_HTML = "app.component.html"; @@ -75,8 +77,8 @@ public static Map angularFiles() { Map.entry(APP_COMPONENT, primaryApp), Map.entry(APP_COMPONENT_HTML, primaryApp), Map.entry(APP_COMPONENT_CSS, primaryApp), - Map.entry("app-routing.module.ts", primaryApp), - Map.entry("app-routing.module.spec.ts", primaryApp), + Map.entry(APP_ROUTING_MODULE, primaryApp), + Map.entry(APP_ROUTING_MODULE_SPEC, primaryApp), Map.entry(APP_COMPONENT_SPEC, primaryApp), Map.entry("environment.prod.ts", environments), Map.entry("environment.prod.spec.ts", environments), diff --git a/src/main/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwt.java b/src/main/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwt.java index e8442b426b4..5b51c69610f 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwt.java +++ b/src/main/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwt.java @@ -27,7 +27,13 @@ public static Map angularJwtFiles() { Map.entry("auth-jwt.service.spec.ts", primaryAppAuth), Map.entry("login.service.ts", primaryAppLogin), Map.entry("login.service.spec.ts", primaryAppLogin), - Map.entry("login.model.ts", primaryAppLogin) + Map.entry("login.model.ts", primaryAppLogin), + Map.entry("login.component.css", primaryAppLogin), + Map.entry("login.component.html", primaryAppLogin), + Map.entry("login.component.spec.ts", primaryAppLogin), + Map.entry("login.component.ts", primaryAppLogin), + Map.entry("login.module.ts", primaryAppLogin), + Map.entry("login.route.ts", primaryAppLogin) ); } } diff --git a/src/main/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwtDomainService.java b/src/main/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwtDomainService.java index d67f8b161ec..655dc8cdc4c 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwtDomainService.java +++ b/src/main/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwtDomainService.java @@ -2,7 +2,6 @@ import static tech.jhipster.lite.common.domain.FileUtils.getPath; import static tech.jhipster.lite.generator.client.angular.core.domain.Angular.*; -import static tech.jhipster.lite.generator.client.angular.core.domain.Angular.APP_COMPONENT_SPEC; import static tech.jhipster.lite.generator.project.domain.Constants.MAIN_WEBAPP; import static tech.jhipster.lite.generator.project.domain.DefaultConfig.BASE_NAME; @@ -46,100 +45,38 @@ public void addJwtDependencies(Project project) { } public void updateAngularFilesForJwt(Project project) { - String oldHtml = ""; + String oldHtml = "// jhipster-needle-angular-jwt-login-form"; String newHtml = """ - - -
- -
-
You are logged in as user "{{ account?.login }}".
- -
-
-
-
"""; - projectRepository.replaceText(project, APP, APP_COMPONENT_HTML, oldHtml, newHtml); + { + path: '', + loadChildren: () => import('./../../../login/login.module').then(m => m.LoginModule), + }"""; + projectRepository.replaceText(project, APP, APP_ROUTING_MODULE, oldHtml, newHtml); - oldHtml = "import \\{ Component, OnInit \\} from '@angular/core';"; + oldHtml = "import \\{ AppRoutingModule \\} from './app-routing.module';"; newHtml = """ - import { Component, OnDestroy, OnInit } from '@angular/core'; - import { FormBuilder, Validators } from '@angular/forms'; - import { Subject, takeUntil } from 'rxjs'; - import { AccountService } from '../../../auth/account.service'; - import { LoginService } from '../../../login/login.service'; - import { Account } from '../../../auth/account.model';"""; - projectRepository.replaceText(project, APP, APP_COMPONENT, oldHtml, newHtml); - - oldHtml = "export class AppComponent implements OnInit \\{"; - newHtml = "export class AppComponent implements OnInit, OnDestroy {"; - projectRepository.replaceText(project, APP, APP_COMPONENT, oldHtml, newHtml); + import { TestBed } from '@angular/core/testing'; + import { Router } from '@angular/router'; + import { RouterTestingModule } from '@angular/router/testing'; + import { AppRoutingModule, routes } from './app-routing.module';"""; + projectRepository.replaceText(project, APP, APP_ROUTING_MODULE_SPEC, oldHtml, newHtml); - oldHtml = "appName = '';"; + oldHtml = "// jhipster-needle-angular-jwt-login-form"; newHtml = """ - appName = ''; - - private readonly destroy\\$ = new Subject(); - - account: Account | null = null; - - loginForm = this.fb.group({ - username: [null, [Validators.required]], - password: [null, [Validators.required]] - }); - - constructor( - private accountService: AccountService, - private loginService: LoginService, - private fb: FormBuilder - ) {} - """; - projectRepository.replaceText(project, APP, APP_COMPONENT, oldHtml, newHtml); - - oldHtml = """ - } - } + let router: Router; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule.withRoutes(routes)] + }).compileComponents(); + router = TestBed.get(Router); + router.initialNavigation(); + }); """; - newHtml = - """ - this.accountService - .getAuthenticationState() - .pipe(takeUntil(this.destroy\\$)) - .subscribe(account => this.account = account); - } - - ngOnDestroy(): void { - this.destroy\\$.next(); - this.destroy\\$.complete(); - } - - login(): void { - this.loginService - .login({ - username: this.loginForm.get('username')!.value, - password: this.loginForm.get('password')!.value, - }) - .subscribe(); - } - - logout(): void { - this.loginService.logout(); - } - }"""; - projectRepository.replaceText(project, APP, APP_COMPONENT, oldHtml, newHtml); + projectRepository.replaceText(project, APP, APP_ROUTING_MODULE_SPEC, oldHtml, newHtml); oldHtml = "import \\{ NgModule \\} from '@angular/core';"; newHtml = @@ -159,9 +96,9 @@ public void updateAngularFilesForJwt(Project project) { projectRepository.replaceText(project, APP, APP_MODULE, oldHtml, newHtml); oldHtml = - "imports: \\[BrowserAnimationsModule, MatToolbarModule, MatIconModule, MatButtonModule, MatButtonToggleModule, MatFormFieldModule, MatInputModule, MatCardModule, MatDividerModule, BrowserModule, AppRoutingModule\\],"; + "imports: \\[BrowserAnimationsModule, MatToolbarModule, MatIconModule, MatButtonModule, MatButtonToggleModule, BrowserModule, AppRoutingModule\\],"; newHtml = - "imports: [BrowserAnimationsModule, MatToolbarModule, MatIconModule, MatButtonModule, MatButtonToggleModule, MatFormFieldModule, MatInputModule, MatCardModule, MatDividerModule, BrowserModule, AppRoutingModule, HttpClientModule, ReactiveFormsModule, NgxWebstorageModule.forRoot()],"; + "imports: [BrowserAnimationsModule, MatToolbarModule, MatIconModule, MatButtonModule, MatButtonToggleModule, BrowserModule, AppRoutingModule, HttpClientModule, ReactiveFormsModule, NgxWebstorageModule.forRoot()],"; projectRepository.replaceText(project, APP, APP_MODULE, oldHtml, newHtml); oldHtml = "bootstrap: \\[AppComponent\\],"; @@ -177,169 +114,6 @@ public void updateAngularFilesForJwt(Project project) { ],"""; projectRepository.replaceText(project, APP, APP_MODULE, oldHtml, newHtml); - oldHtml = - """ - import \\{ ComponentFixture, TestBed, waitForAsync \\} from '@angular/core/testing'; - - import \\{ AppComponent \\} from './app.component'; - - describe\\('App Component', \\(\\) => \\{ - let comp: AppComponent; - let fixture: ComponentFixture; - - beforeEach\\( - waitForAsync\\(\\(\\) => \\{ - TestBed.configureTestingModule\\(\\{ - declarations: \\[AppComponent\\], - \\}\\) - .overrideTemplate\\(AppComponent, ''\\) - .compileComponents\\(\\); - \\}\\) - \\); - - beforeEach\\(\\(\\) => \\{ - fixture = TestBed.createComponent\\(AppComponent\\); - comp = fixture.componentInstance; - \\}\\); - - describe\\('ngOnInit', \\(\\) => \\{ - it\\('should have appName', \\(\\) => \\{ - // WHEN - comp.ngOnInit\\(\\); - - // THEN - expect\\(comp.appName\\).toEqual\\('"""; - newHtml = - """ - import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; - import { HttpClientTestingModule } from '@angular/common/http/testing'; - import { NgxWebstorageModule } from 'ngx-webstorage'; - import { FormBuilder } from '@angular/forms'; - import { of, Subject } from 'rxjs'; - import { LoginService } from '../../../login/login.service'; - import { AccountService } from '../../../auth/account.service'; - import { Account } from '../../../auth/account.model'; - - import { AppComponent } from './app.component'; - - describe('App Component', () => { - let comp: AppComponent; - let fixture: ComponentFixture; - let mockAccountService: AccountService; - let mockLoginService: LoginService; - const account: Account = { - activated: true, - authorities: [], - email: '', - firstName: null, - langKey: '', - lastName: null, - login: 'login', - }; - - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [AppComponent], - imports: [HttpClientTestingModule, NgxWebstorageModule.forRoot()], - providers: [ - FormBuilder, - AccountService, - { - provide: LoginService, - useValue: { - login: jest.fn(() => of({})), - logout: jest.fn(() => of({})), - }, - }, - ], - }) - .overrideTemplate(AppComponent, '') - .compileComponents(); - }) - ); - - beforeEach(() => { - fixture = TestBed.createComponent(AppComponent); - comp = fixture.componentInstance; - mockLoginService = TestBed.inject(LoginService); - mockAccountService = TestBed.inject(AccountService); - }); - - describe('ngOnInit', () => { - it('should have appName', () => { - // GIVEN - const authenticationState = new Subject(); - mockAccountService.getAuthenticationState = jest.fn(() => authenticationState.asObservable()); - - // WHEN - comp.ngOnInit(); - - // THEN - expect(comp.appName).toEqual('"""; - projectRepository.replaceText(project, APP, APP_COMPONENT_SPEC, oldHtml, newHtml); - - oldHtml = """ - \\}\\); - \\}\\); - - \\}\\);"""; - newHtml = - """ - expect(mockAccountService.getAuthenticationState).toHaveBeenCalled(); - - // THEN - expect(comp.account).toBeNull(); - - // WHEN - authenticationState.next(account); - - // THEN - expect(comp.account).toEqual(account); - - // WHEN - authenticationState.next(null); - - // THEN - expect(comp.account).toBeNull(); - }); - }); - - describe('login', () => { - it('should authenticate the user', () => { - // GIVEN - const credentials = { - username: 'admin', - password: 'admin', - }; - - comp.loginForm.patchValue({ - username: 'admin', - password: 'admin', - }); - - // WHEN - comp.login(); - - // THEN - expect(mockLoginService.login).toHaveBeenCalledWith(credentials); - }); - }); - - describe('logout', () => { - it('should logout the user', () => { - // WHEN - comp.logout(); - - // THEN - expect(mockLoginService.logout).toHaveBeenCalled(); - }); - }); - - }); - """; - projectRepository.replaceText(project, APP, APP_COMPONENT_SPEC, oldHtml, newHtml); - oldHtml = "9000"; newHtml = """ 9000, diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app-routing.module.spec.ts.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app-routing.module.spec.ts.mustache index fb3a7ad9e1a..696c39ed124 100644 --- a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app-routing.module.spec.ts.mustache +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app-routing.module.spec.ts.mustache @@ -1,6 +1,7 @@ import { AppRoutingModule } from './app-routing.module'; describe('AppRoutingModule', () => { + // jhipster-needle-angular-jwt-login-form it('should be defined', () => { expect(AppRoutingModule).toBeDefined(); }); diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app-routing.module.ts.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app-routing.module.ts.mustache index f3daf250ad2..97a3b31fdb5 100644 --- a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app-routing.module.ts.mustache +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app-routing.module.ts.mustache @@ -1,7 +1,9 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -const routes: Routes = []; +export const routes: Routes = [ + // jhipster-needle-angular-jwt-login-form +]; @NgModule({ imports: [RouterModule.forRoot(routes)], diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.css.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.css.mustache index 3753a8f4310..47dacdd1080 100644 --- a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.css.mustache +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.css.mustache @@ -11,28 +11,6 @@ width: 250px; } -.login-form { - min-width: 150px; - max-width: 500px; - width: 100%; -} - -.form-field-full-width { - width: 100%; -} - -.toolbar-spacer { - flex: 1 1 auto; -} - -mat-card{ - width: 350px; - display: block; - margin-left:auto; - margin-right:auto; - margin-top: 20px; -} - #footer { width: 100%; text-align: center; diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.html.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.html.mustache index 6f0ce9d53b6..97bd7927d77 100644 --- a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.html.mustache +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.html.mustache @@ -9,7 +9,7 @@ - + - - diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.ts.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.ts.mustache index 17302e322c6..8361874f3fa 100644 --- a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.ts.mustache +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.component.ts.mustache @@ -5,7 +5,7 @@ import { Component, OnInit } from '@angular/core'; templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) -export class AppComponent implements OnInit { +export class AppComponent implements OnInit{ appName = ''; ngOnInit(): void { diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.module.ts.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.module.ts.mustache index 5e19d76b239..a04ecdb44af 100644 --- a/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.module.ts.mustache +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/common/primary/app/app.module.ts.mustache @@ -9,14 +9,10 @@ import { MatToolbarModule } from '@angular/material/toolbar'; import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatCardModule } from '@angular/material/card'; -import { MatDividerModule } from '@angular/material/divider'; @NgModule({ declarations: [AppComponent], - imports: [BrowserAnimationsModule, MatToolbarModule, MatIconModule, MatButtonModule, MatButtonToggleModule, MatFormFieldModule, MatInputModule, MatCardModule, MatDividerModule, BrowserModule, AppRoutingModule], + imports: [BrowserAnimationsModule, MatToolbarModule, MatIconModule, MatButtonModule, MatButtonToggleModule, BrowserModule, AppRoutingModule], bootstrap: [AppComponent], }) export class AppModule {} diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.css.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.css.mustache new file mode 100644 index 00000000000..6607be9509e --- /dev/null +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.css.mustache @@ -0,0 +1,29 @@ +.jhipster-logo { + display: block; + margin-left: auto; + margin-right: auto; + margin-top: 20px; + width: 250px; +} + +.login-form { + min-width: 150px; + max-width: 500px; + width: 100%; +} + +.form-field-full-width { + width: 100%; +} + +.toolbar-spacer { + flex: 1 1 auto; +} + +mat-card { + width: 350px; + display: block; + margin-left: auto; + margin-right: auto; + margin-top: 20px; +} diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.html.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.html.mustache new file mode 100644 index 00000000000..c7526eac7a7 --- /dev/null +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.html.mustache @@ -0,0 +1,30 @@ + + +
+ +
+
You are logged in as user "{{ account?.login }}".
+ +
+
+
+
diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.spec.ts.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.spec.ts.mustache new file mode 100644 index 00000000000..8a091ee582b --- /dev/null +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.spec.ts.mustache @@ -0,0 +1,114 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { NgxWebstorageModule } from 'ngx-webstorage'; +import { FormBuilder } from '@angular/forms'; +import { of, Subject } from 'rxjs'; +import { LoginService } from './login.service'; +import { AccountService } from '../auth/account.service'; +import { Account } from '../auth/account.model'; + +import { LoginComponent } from './login.component'; + +describe('Login Component', () => { + let comp: LoginComponent; + let fixture: ComponentFixture; + let mockAccountService: AccountService; + let mockLoginService: LoginService; + const account: Account = { + activated: true, + authorities: [], + email: '', + firstName: null, + langKey: '', + lastName: null, + login: 'login', + }; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [LoginComponent], + imports: [HttpClientTestingModule, NgxWebstorageModule.forRoot()], + providers: [ + FormBuilder, + AccountService, + { + provide: LoginService, + useValue: { + login: jest.fn(() => of({})), + logout: jest.fn(() => of({})), + }, + }, + ], + }) + .overrideTemplate(LoginComponent, '') + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LoginComponent); + comp = fixture.componentInstance; + mockLoginService = TestBed.inject(LoginService); + mockAccountService = TestBed.inject(AccountService); + }); + + describe('ngOnInit', () => { + it('should have appName', () => { + // GIVEN + const authenticationState = new Subject(); + mockAccountService.getAuthenticationState = jest.fn(() => authenticationState.asObservable()); + + // WHEN + comp.ngOnInit(); + + // THEN + expect(comp.appName).toEqual('{{baseName}}'); + expect(mockAccountService.getAuthenticationState).toHaveBeenCalled(); + + // THEN + expect(comp.account).toBeNull(); + + // WHEN + authenticationState.next(account); + + // THEN + expect(comp.account).toEqual(account); + + // WHEN + authenticationState.next(null); + + // THEN + expect(comp.account).toBeNull(); + }); + }); + + describe('login', () => { + it('should authenticate the user', () => { + // GIVEN + const credentials = { + username: 'admin', + password: 'admin', + }; + + comp.loginForm.patchValue({ + username: 'admin', + password: 'admin', + }); + + // WHEN + comp.login(); + + // THEN + expect(mockLoginService.login).toHaveBeenCalledWith(credentials); + }); + }); + + describe('logout', () => { + it('should logout the user', () => { + // WHEN + comp.logout(); + + // THEN + expect(mockLoginService.logout).toHaveBeenCalled(); + }); + }); +}); diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.ts.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.ts.mustache new file mode 100644 index 00000000000..c99d9ee3f00 --- /dev/null +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.component.ts.mustache @@ -0,0 +1,52 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, Validators } from '@angular/forms'; +import { Subject, takeUntil } from 'rxjs'; +import { AccountService } from '../auth/account.service'; +import { LoginService } from '../login/login.service'; +import { Account } from '../auth/account.model'; + +@Component({ + selector: 'jh-lite-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.css'], +}) +export class LoginComponent implements OnInit, OnDestroy { + appName = ''; + + private readonly destroy$ = new Subject(); + + account: Account | null = null; + + loginForm = this.fb.group({ + username: [null, [Validators.required]], + password: [null, [Validators.required]], + }); + + constructor(private accountService: AccountService, private loginService: LoginService, private fb: FormBuilder) {} + + ngOnInit(): void { + this.appName = '{{baseName}}'; + this.accountService + .getAuthenticationState() + .pipe(takeUntil(this.destroy$)) + .subscribe(account => (this.account = account)); + } + + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } + + login(): void { + this.loginService + .login({ + username: this.loginForm.get('username')!.value, + password: this.loginForm.get('password')!.value, + }) + .subscribe(); + } + + logout(): void { + this.loginService.logout(); + } +} diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.module.ts.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.module.ts.mustache new file mode 100644 index 00000000000..4a178b65a46 --- /dev/null +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.module.ts.mustache @@ -0,0 +1,33 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { LoginComponent } from './login.component'; +import { loginRoute } from './login.route'; + +import { ReactiveFormsModule } from '@angular/forms'; +import { CommonModule } from '@angular/common'; + +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatCardModule } from '@angular/material/card'; +import { MatDividerModule } from '@angular/material/divider'; + +@NgModule({ + imports: [ + MatIconModule, + MatButtonModule, + MatButtonToggleModule, + MatFormFieldModule, + MatInputModule, + MatCardModule, + MatDividerModule, + ReactiveFormsModule, + CommonModule, + RouterModule.forChild([loginRoute]) + ], + declarations: [LoginComponent], +}) +export class LoginModule {} diff --git a/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.route.ts.mustache b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.route.ts.mustache new file mode 100644 index 00000000000..128c667d26e --- /dev/null +++ b/src/main/resources/generator/client/angular/src/main/webapp/app/login/login.route.ts.mustache @@ -0,0 +1,8 @@ +import { Route } from '@angular/router'; + +import { LoginComponent } from './login.component'; + +export const loginRoute: Route = { + path: '', + component: LoginComponent, +}; diff --git a/src/test/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwtDomainServiceTest.java b/src/test/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwtDomainServiceTest.java index 592b6b06156..6a8ef11c6cc 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwtDomainServiceTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/angular/security/jwt/domain/AngularJwtDomainServiceTest.java @@ -81,6 +81,6 @@ void shouldAddAngularJwtFiles() { angularJwtDomainService.addAngularJwtFiles(project); - verify(projectRepository, times(9)).template(any(Project.class), anyString(), anyString(), anyString()); + verify(projectRepository, times(15)).template(any(Project.class), anyString(), anyString(), anyString()); } }