From 65335ed485e3eb844bc7c8f9db1a6ab0af76e132 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Fri, 29 Jan 2021 17:42:28 +0200 Subject: Implemented functionality for modifying languages and technologies in the user settings page with a rough UI --- .../profile-settings.component.html | 21 ++++ .../profile-settings/profile-settings.component.ts | 125 ++++++++++++++++++++- .../src/app/services/user.service.ts | 5 +- 3 files changed, 145 insertions(+), 6 deletions(-) (limited to 'src/DevHive.Angular') diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html index 8da7f86..16b537c 100644 --- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html +++ b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html @@ -58,6 +58,27 @@ + +
+ Type in your desired languages, separated by a space. + + Available languages: +
+ {{ lang.name }} +
+
+ + +
+ Type in your desired technologies, separated by a space. + + Available technologies: +
+ {{ tech.name }} +
+
+ + diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts index 0ea5ea2..5be160e 100644 --- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts +++ b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts @@ -4,8 +4,10 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'; import {Router} from '@angular/router'; import {AppConstants} from 'src/app/app-constants.module'; +import {LanguageService} from 'src/app/services/language.service'; import {UserService} from 'src/app/services/user.service'; -import {User} from 'src/models/identity/user'; +import {TechnologyService} from 'src/app/services/technology.service'; +import {Language, Technology, User} from 'src/models/identity/user'; import {ErrorBarComponent} from '../error-bar/error-bar.component'; import {SuccessBarComponent} from '../success-bar/success-bar.component'; @@ -22,12 +24,16 @@ export class ProfileSettingsComponent implements OnInit { public dataArrived = false; public user: User; public deleteAccountConfirm = false; + public showLanguages = false; + public availableLanguages: Language[] = []; + public showTechnologies = false; + public availableTechnologies: Technology[] = []; - constructor(private _router: Router, private _userService: UserService, private _fb: FormBuilder, private _location: Location) + constructor(private _router: Router, private _userService: UserService, private _languageService: LanguageService, private _technologyService: TechnologyService, private _fb: FormBuilder, private _location: Location) { } ngOnInit(): void { - this._urlUsername = this._router.url.substring(9) + this._urlUsername = this._router.url.substring(9); this._urlUsername = this._urlUsername.substring(0, this._urlUsername.length - 9); this.user = this._userService.getDefaultUser(); @@ -35,6 +41,17 @@ export class ProfileSettingsComponent implements OnInit { (res: object) => this.finishUserLoading(res), (err: HttpErrorResponse) => { this._router.navigate(['/not-found']); } ); + + this._languageService.getAllLanguagesWithSessionStorageRequest().subscribe( + (result: object) => { + this.availableLanguages = result as Language[]; + } + ); + this._technologyService.getAllTechnologiesWithSessionStorageRequest().subscribe( + (result: object) => { + this.availableTechnologies = result as Technology[]; + } + ); } private finishUserLoading(res: object): void { @@ -89,14 +106,51 @@ export class ProfileSettingsComponent implements OnInit { Validators.minLength(3), Validators.pattern('.*[0-9].*') // Check if password contains atleast one number ]), + + // For language we have two different controls, + // the first one is used for input, the other one for sending data + // because if we edit the control for input, + // we're also gonna change the input field in the HTML + languageInput: new FormControl(''), // The one for input + languages: new FormControl(''), // The one that is sent + + // For technologies it's the same as it is with languages + technologyInput: new FormControl(''), + technologies: new FormControl('') }); + this.getLanguagesForShowing() + .then(value => this.updateUserFormGroup.patchValue({ languageInput : value })); + + this.getTechnologiesForShowing() + .then(value => this.updateUserFormGroup.patchValue({ technologyInput : value })); + this.updateUserFormGroup.valueChanges.subscribe(() => { this._successBar.hideMsg(); this._errorBar.hideError(); }); } + private getLanguagesForShowing(): Promise { + return new Promise(resolve => + this._languageService.getFullLanguagesFromIncomplete(this.user.languages) + .then(value => { + this.user.languages = value; + resolve(value.map(x => x.name).join(' ')); + }) + ); + } + + private getTechnologiesForShowing(): Promise { + return new Promise(resolve => + this._technologyService.getFullTechnologiesFromIncomplete(this.user.technologies) + .then(value => { + this.user.technologies = value; + resolve(value.map(x => x.name).join(' ')); + }) + ); + } + private bailOnBadToken(): void { this._userService.logoutUserFromSessionStorage(); this._router.navigate(['/login']); @@ -105,12 +159,69 @@ export class ProfileSettingsComponent implements OnInit { onSubmit(): void { this._successBar.hideMsg(); this._errorBar.hideError(); + + this.patchLanguagesControl(); + this.patchTechnologiesControl(); + this._userService.putUserFromSessionStorageRequest(this.updateUserFormGroup).subscribe( res => this._successBar.showMsg('Profile updated successfully!'), (err: HttpErrorResponse) => this._errorBar.showError(err) ); } + private patchLanguagesControl(): void { + // Get user input + const langControl = this.updateUserFormGroup.get('languageInput')?.value as string ?? ''; + + if (langControl === '') { + // Add the data to the form (to the value that is going to be sent) + this.updateUserFormGroup.patchValue({ + languages : [] + }); + } + else { + const names = langControl.split(' '); + + // Transfer user input to objects of type { "name": "value" } + const actualLanguages = []; + for (const lName of names) { + actualLanguages.push({ name : lName }); + } + + // Add the data to the form (to the value that is going to be sent) + this.updateUserFormGroup.patchValue({ + languages : actualLanguages + }); + } + } + + private patchTechnologiesControl(): void { + // Get user input + const techControl = this.updateUserFormGroup.get('technologyInput')?.value as string ?? ''; + + if (techControl === '') { + // Add the data to the form (to the value that is going to be sent) + this.updateUserFormGroup.patchValue({ + technologies : [] + }); + } + else { + const names = techControl.split(' '); + + // Transfer user input to objects of type { "name": "value" } + const actualTechnologies = []; + for (const tName of names) { + actualTechnologies.push({ name : tName }); + } + + // Add the data to the form (to the value that is going to be sent) + this.updateUserFormGroup.patchValue({ + technologies : actualTechnologies + }); + } + } + + goToProfile(): void { this._router.navigate([this._router.url.substring(0, this._router.url.length - 9)]); } @@ -128,6 +239,14 @@ export class ProfileSettingsComponent implements OnInit { this.goToProfile(); } + toggleLanguages(): void { + this.showLanguages = !this.showLanguages; + } + + toggleTechnologies(): void { + this.showTechnologies = !this.showTechnologies; + } + deleteAccount(): void { if (this.deleteAccountConfirm) { this._userService.deleteUserFromSessionStorageRequest().subscribe( diff --git a/src/DevHive.Angular/src/app/services/user.service.ts b/src/DevHive.Angular/src/app/services/user.service.ts index 5b4b63c..6badf94 100644 --- a/src/DevHive.Angular/src/app/services/user.service.ts +++ b/src/DevHive.Angular/src/app/services/user.service.ts @@ -94,7 +94,6 @@ export class UserService { } putUserRequest(userId: Guid, authToken: string, updateUserFormGroup: FormGroup): Observable { - // TODO?: add a check for form data validity const body = { UserName: updateUserFormGroup.get('username')?.value, Email: updateUserFormGroup.get('email')?.value, @@ -104,8 +103,8 @@ export class UserService { // TODO: make the following fields dynamically selectable Roles: [ { Name: 'User' } ], Friends: [], - Languages: [], - Technologies: [] + Languages: updateUserFormGroup.get('languages')?.value, + Technologies: updateUserFormGroup.get('technologies')?.value }; const options = { params: new HttpParams().set('Id', userId.toString()), -- cgit v1.2.3