diff --git a/src/app/actions/shelters.action.ts b/src/app/actions/shelters.action.ts index c96ca04..0f8a0fc 100644 --- a/src/app/actions/shelters.action.ts +++ b/src/app/actions/shelters.action.ts @@ -1,5 +1,6 @@ import {createAction, props} from '@ngrx/store'; import {Shelter} from '../models/Shelter.models'; +import {BasicAuth} from '../models/BasicAuth.models'; export const deleteShelter = createAction('[test] Delete a shelter', props<{ shelterId: number }>()); export const getAllShelters = createAction('[Shelters Page] Load Shelters'); @@ -9,3 +10,5 @@ export const successAddShelter = createAction('[Shelters Page] Shelter added', p export const successUpdateShelter = createAction('[Shelters Page] Shelter updated', props<{ shelter: Shelter }>()); export const successGetAllShelters = createAction('[Shelters Page] Shelters loaded', props<{ sheltersList: Shelter[] }>()); export const successDeleteShelter = createAction('[Shelters Page] Shelters deleted'); + +export const connexionRequest = createAction('[Login Page] connexion request', props<{ cred: BasicAuth}>()); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0691701..522c936 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,6 +1,6 @@ import {BrowserModule} from '@angular/platform-browser'; import {NgModule} from '@angular/core'; -import {FormsModule} from '@angular/forms'; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; import {RouterModule} from '@angular/router'; import {AppRoutingModule} from './app.routing'; @@ -16,14 +16,16 @@ import {environment} from '../environments/environment'; import {EffectsModule} from '@ngrx/effects'; import {SheltersEffects} from './effects/shelters.effect'; import {StoreModule} from '@ngrx/store'; -import {sheltersReducer} from './reducers/shelters.reducer'; +import {authReducer, sheltersReducer} from './reducers/shelters.reducer'; +import {BasicFormComponent} from './auth/basic-form/basic-form.component'; @NgModule({ declarations: [ AppComponent, NavbarComponent, - FooterComponent + FooterComponent, + BasicFormComponent ], imports: [ BrowserModule, @@ -33,9 +35,10 @@ import {sheltersReducer} from './reducers/shelters.reducer'; ComponentsModule, SheltersModule, AppRoutingModule, - ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }), + ServiceWorkerModule.register('ngsw-worker.js', {enabled: environment.production}), EffectsModule.forRoot([SheltersEffects]), - StoreModule.forRoot({sheltersList: sheltersReducer}) + StoreModule.forRoot({sheltersList: sheltersReducer, cred: authReducer}), + ReactiveFormsModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/auth/basic-form/basic-form.component.css b/src/app/auth/basic-form/basic-form.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/auth/basic-form/basic-form.component.html b/src/app/auth/basic-form/basic-form.component.html new file mode 100644 index 0000000..5ee0ab9 --- /dev/null +++ b/src/app/auth/basic-form/basic-form.component.html @@ -0,0 +1,17 @@ +
+
+
+ + + + + + +
+ +
+
+
+
diff --git a/src/app/auth/basic-form/basic-form.component.spec.ts b/src/app/auth/basic-form/basic-form.component.spec.ts new file mode 100644 index 0000000..8907c25 --- /dev/null +++ b/src/app/auth/basic-form/basic-form.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BasicFormComponent } from './basic-form.component'; + +describe('BasicFormComponent', () => { + let component: BasicFormComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BasicFormComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BasicFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/auth/basic-form/basic-form.component.ts b/src/app/auth/basic-form/basic-form.component.ts new file mode 100644 index 0000000..c153644 --- /dev/null +++ b/src/app/auth/basic-form/basic-form.component.ts @@ -0,0 +1,50 @@ +import {Component, OnInit} from '@angular/core'; +import {BasicAuth} from '../../models/BasicAuth.models'; +import {FormControl, FormGroup} from '@angular/forms'; +import {connexionRequest} from '../../actions/shelters.action'; +import {select, Store} from '@ngrx/store'; +import {Clone} from '../../utils/clone'; +import {Observable} from 'rxjs'; + +@Component({ + selector: 'app-basic-form', + templateUrl: './basic-form.component.html', + styleUrls: ['./basic-form.component.css'] +}) +export class BasicFormComponent implements OnInit { + + profileForm = new FormGroup({ + login: new FormControl(''), + password: new FormControl('') + }); + private cred$: Observable = this.store.pipe(select('cred')); + private cred: BasicAuth; + private edit: boolean = true; + + constructor(private clone: Clone, private store: Store<{ cred: BasicAuth }>) { + this.cred$.subscribe((newCreds: BasicAuth) => { + console.log('credentials used', newCreds); + this.cred = newCreds; + } + ); + } + + ngOnInit(): void { + this.profileForm.get('login').setValue(this.cred.login); + this.profileForm.get('password').setValue(this.cred.password); + } + + /** + * + */ + onSubmit() { + this.cred = this.clone.simpleClone(this.cred); + this.cred.login = this.profileForm.value.login; + this.cred.password = this.profileForm.value.password; + + this.store.dispatch(connexionRequest({cred: this.cred})); + + // TODO: change the edit status only after action is done (callback ?) + this.edit = !this.edit; + } +} diff --git a/src/app/effects/shelters.effect.ts b/src/app/effects/shelters.effect.ts index 0f5351e..6bf7c42 100644 --- a/src/app/effects/shelters.effect.ts +++ b/src/app/effects/shelters.effect.ts @@ -5,6 +5,7 @@ import {Injectable} from '@angular/core'; import {SheltersService} from '../services/shelters.service'; import { addShelter, + connexionRequest, deleteShelter, getAllShelters, successAddShelter, diff --git a/src/app/models/BasicAuth.models.ts b/src/app/models/BasicAuth.models.ts new file mode 100644 index 0000000..c6a0914 --- /dev/null +++ b/src/app/models/BasicAuth.models.ts @@ -0,0 +1,4 @@ +export interface BasicAuth { + login: string + password: string +} diff --git a/src/app/reducers/shelters.reducer.ts b/src/app/reducers/shelters.reducer.ts index 73759bc..76f55c6 100644 --- a/src/app/reducers/shelters.reducer.ts +++ b/src/app/reducers/shelters.reducer.ts @@ -1,17 +1,32 @@ import {createReducer, on} from '@ngrx/store'; import { addShelter, + connexionRequest, deleteShelter, getAllShelters, successAddShelter, successDeleteShelter, - successGetAllShelters, successUpdateShelter, updateShelter + successGetAllShelters, + successUpdateShelter, + updateShelter } from '../actions/shelters.action'; import {Shelter} from '../models/Shelter.models'; +import {BasicAuth} from '../models/BasicAuth.models'; export let sheltersList: Shelter[] = undefined; +export let cred: BasicAuth = { + login: 'admin', + password: 'nimda' +}; -const _counterReducer = createReducer(sheltersList, +const _authReducer = createReducer(cred, + on(connexionRequest, (state, action) => { + cred = action.cred; + return cred; + }) +); + +const _sheltersReducer = createReducer(sheltersList, on(successDeleteShelter, (state) => { console.log('shelter deleted reducer'); return sheltersList; @@ -52,5 +67,9 @@ const _counterReducer = createReducer(sheltersList, ); export function sheltersReducer(state, action) { - return _counterReducer(state, action); + return _sheltersReducer(state, action); +} + +export function authReducer(state, action) { + return _authReducer(state, action); } diff --git a/src/app/services/shelters.service.ts b/src/app/services/shelters.service.ts index 01cb606..7777196 100644 --- a/src/app/services/shelters.service.ts +++ b/src/app/services/shelters.service.ts @@ -5,6 +5,8 @@ import {ShelterList} from '../models/ShelterList.models'; import {environment} from '../../environments/environment'; import {Observable} from 'rxjs'; import {map} from 'rxjs/operators'; +import {BasicAuth} from '../models/BasicAuth.models'; +import {select, Store} from '@ngrx/store'; @Injectable({ providedIn: 'root' @@ -21,8 +23,21 @@ export class SheltersService { private uri = 'api/v1/shelters'; private url = environment.baseUrl + '/' + this.uri; private shelterList$: Observable; + private cred$: Observable = this.store.pipe(select('cred')); - constructor(private _httpClient: HttpClient) { + constructor(private _httpClient: HttpClient, private store: Store<{ cred: BasicAuth }>) { + this.cred$.subscribe((newCreds: BasicAuth) => { + console.log('credentials used', newCreds); + this.credentials = newCreds.login + ':' + newCreds.password; + // TODO: modify instead of recreate + this.httpOptions = { + headers: new HttpHeaders({ + 'Content-Type': 'application/json', + 'Authorization': 'Basic ' + btoa(this.credentials) + }) + }; + } + ); } /** diff --git a/src/app/shelters/shelter/shelter.component.ts b/src/app/shelters/shelter/shelter.component.ts index ae9d05f..9350c2d 100644 --- a/src/app/shelters/shelter/shelter.component.ts +++ b/src/app/shelters/shelter/shelter.component.ts @@ -3,6 +3,10 @@ import {Shelter} from '../../models/Shelter.models'; import {FormControl, FormGroup} from '@angular/forms'; import {deleteShelter, updateShelter} from '../../actions/shelters.action'; import {Store} from '@ngrx/store'; +import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; +import {BasicFormComponent} from '../../auth/basic-form/basic-form.component'; +import {Clone} from '../../utils/clone'; +import {BasicAuth} from '../../models/BasicAuth.models'; @Component({ selector: 'shelter', @@ -19,7 +23,7 @@ export class ShelterComponent implements OnInit { availableBeds: new FormControl(''), }); - constructor(private store: Store<{ sheltersList: Shelter[] }>) { + constructor(private clone: Clone, private store: Store<{ cred: BasicAuth }>, private modalService: NgbModal) { } ngOnInit(): void { @@ -31,20 +35,23 @@ export class ShelterComponent implements OnInit { * call the effect of updating a shelter */ onSubmit() { - this.shelter = this.simpleClone(this.shelter); + this.shelter = this.clone.simpleClone(this.shelter); this.shelter.address = this.profileForm.value.address; this.shelter.availableBeds = this.profileForm.value.availableBeds; + + //TODO: check if user is connected + + // display modal if he's not + const modalRef = this.modalService.open(BasicFormComponent); + modalRef.componentInstance.name = 'World'; + + // try request if he is this.store.dispatch(updateShelter({shelter: this.shelter})); - // todo: change the edit status only after action is done (callback ?) - this.edit = !this.edit; - } - /** - * shallow clone of an object - * @param obj - */ - simpleClone(obj: any) { - return Object.assign({}, obj); + // TODO: display spinner + // TODO: change the edit status after action is done (callback ?) + this.edit = !this.edit; + // modalRef.close(); } /** diff --git a/src/app/utils/clone.spec.ts b/src/app/utils/clone.spec.ts new file mode 100644 index 0000000..d37dd94 --- /dev/null +++ b/src/app/utils/clone.spec.ts @@ -0,0 +1,15 @@ +import {TestBed} from '@angular/core/testing'; +import {Clone} from './clone'; + +describe('Clone', () => { + let clone: Clone; + + beforeEach(() => { + TestBed.configureTestingModule({}); + clone = TestBed.inject(Clone); + }); + + it('should be created', () => { + expect(clone).toBeTruthy(); + }); +}); diff --git a/src/app/utils/clone.ts b/src/app/utils/clone.ts new file mode 100644 index 0000000..f663cb2 --- /dev/null +++ b/src/app/utils/clone.ts @@ -0,0 +1,18 @@ +import {Injectable} from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class Clone { + + constructor() { + } + + /** + * shallow clone of an object + * @param obj + */ + simpleClone(obj: any) { + return Object.assign({}, obj); + } +}