From c09f5ab3c090f0937ecd9f985075672b8a5ccb43 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Mon, 1 Feb 2021 12:24:47 +0200 Subject: Added an admin panel, that can be accessed by admin users; implemented modifying languages in admin panel and added beginnings of technology modifying --- .../src/app/app-constants.module.ts | 1 + src/DevHive.Angular/src/app/app-routing.module.ts | 2 + src/DevHive.Angular/src/app/app.module.ts | 4 +- .../admin-panel-page.component.css | 42 +++++ .../admin-panel-page.component.html | 54 +++++++ .../admin-panel-page/admin-panel-page.component.ts | 169 +++++++++++++++++++++ .../app/components/profile/profile.component.html | 1 + .../app/components/profile/profile.component.ts | 6 + .../src/app/services/language.service.ts | 47 ++++++ 9 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.css create mode 100644 src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.html create mode 100644 src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.ts (limited to 'src/DevHive.Angular') diff --git a/src/DevHive.Angular/src/app/app-constants.module.ts b/src/DevHive.Angular/src/app/app-constants.module.ts index 101ab44..82a3513 100644 --- a/src/DevHive.Angular/src/app/app-constants.module.ts +++ b/src/DevHive.Angular/src/app/app-constants.module.ts @@ -15,4 +15,5 @@ export class AppConstants { public static FALLBACK_PROFILE_ICON = 'assets/images/feed/profile-pic.png'; public static SESSION_TOKEN_KEY = 'UserCred'; + public static ADMIN_ROLE_NAME = 'Admin'; } diff --git a/src/DevHive.Angular/src/app/app-routing.module.ts b/src/DevHive.Angular/src/app/app-routing.module.ts index e4e3d63..4367db7 100644 --- a/src/DevHive.Angular/src/app/app-routing.module.ts +++ b/src/DevHive.Angular/src/app/app-routing.module.ts @@ -7,6 +7,7 @@ import { ProfileComponent } from './components/profile/profile.component'; import { ProfileSettingsComponent } from './components/profile-settings/profile-settings.component'; import { NotFoundComponent } from './components/not-found/not-found.component'; import { PostPageComponent } from './components/post-page/post-page.component'; +import {AdminPanelPageComponent} from './components/admin-panel-page/admin-panel-page.component'; const routes: Routes = [ { path: '', component: FeedComponent }, @@ -15,6 +16,7 @@ const routes: Routes = [ { path: 'profile/:username', component: ProfileComponent }, { path: 'profile/:username/settings', component: ProfileSettingsComponent }, { path: 'post/:id', component: PostPageComponent }, + { path: 'admin-panel', component: AdminPanelPageComponent }, { path: 'not-found', component: NotFoundComponent }, { path: '**', component: NotFoundComponent } ]; diff --git a/src/DevHive.Angular/src/app/app.module.ts b/src/DevHive.Angular/src/app/app.module.ts index 1867787..bd96233 100644 --- a/src/DevHive.Angular/src/app/app.module.ts +++ b/src/DevHive.Angular/src/app/app.module.ts @@ -20,6 +20,7 @@ import { LoadingComponent } from './components/loading/loading.component'; import { ErrorBarComponent } from './components/error-bar/error-bar.component'; import { SuccessBarComponent } from './components/success-bar/success-bar.component'; import { PostPageComponent } from './components/post-page/post-page.component'; +import { AdminPanelPageComponent } from './components/admin-panel-page/admin-panel-page.component'; @NgModule({ declarations: [ @@ -34,7 +35,8 @@ import { PostPageComponent } from './components/post-page/post-page.component'; LoadingComponent, ErrorBarComponent, SuccessBarComponent, - PostPageComponent + PostPageComponent, + AdminPanelPageComponent ], imports: [ BrowserModule, diff --git a/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.css b/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.css new file mode 100644 index 0000000..1f98e20 --- /dev/null +++ b/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.css @@ -0,0 +1,42 @@ +#content { + max-width: 22em; + justify-content: start; +} + +hr { + width: calc(100% - 1em); + color: black; + border: 1px solid black; +} + +#navigation { + width: 100%; + display: flex; +} + +#navigation > * { + flex: 1; + margin-left: .4em; +} + +.submit-btn:first-of-type { + margin-left: 0 !important; +} + +#all-languages, #all-technologies { + display: flex; + flex-wrap: wrap; +} + +.flexbox { + display: flex; +} + +.flexbox > * { + flex: 1; + margin-left: 1em; +} + +.flexbox > *:first-child { + margin-left: 0; +} diff --git a/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.html b/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.html new file mode 100644 index 0000000..c11f730 --- /dev/null +++ b/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.html @@ -0,0 +1,54 @@ + + +
+ +
+
+ + + +
+
+ + +
+ +
+ + +
+ +
+ +
+ +
+ Available languages: +
+
+ {{ lang.name }} +
+
+
+
+ +
+
+ +
+ +
+
+ Available technologies: +
+
+ {{ tech.name }} +
+
+
+
+
diff --git a/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.ts b/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.ts new file mode 100644 index 0000000..0cb25ee --- /dev/null +++ b/src/DevHive.Angular/src/app/components/admin-panel-page/admin-panel-page.component.ts @@ -0,0 +1,169 @@ +import { HttpErrorResponse } from '@angular/common/http'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup } 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 { TechnologyService } from 'src/app/services/technology.service'; +import { TokenService } from 'src/app/services/token.service'; +import { UserService } from 'src/app/services/user.service'; +import { User } from 'src/models/identity/user'; +import { Language } from 'src/models/language'; +import { Technology } from 'src/models/technology'; +import { ErrorBarComponent } from '../error-bar/error-bar.component'; +import { SuccessBarComponent } from '../success-bar/success-bar.component'; + +@Component({ + selector: 'app-admin-panel-page', + templateUrl: './admin-panel-page.component.html', + styleUrls: ['./admin-panel-page.component.css'] +}) +export class AdminPanelPageComponent implements OnInit { + @ViewChild(ErrorBarComponent) private _errorBar: ErrorBarComponent; + @ViewChild(SuccessBarComponent) private _successBar: SuccessBarComponent; + public dataArrived = false; + public showLanguages = false; + public showTechnologies = false; + public availableLanguages: Language[]; + public availableTechnologies: Technology[]; + public languageForm: FormGroup; + + constructor(private _router: Router, private _fb: FormBuilder, private _userService: UserService, private _languageService: LanguageService, private _technologyService: TechnologyService, private _tokenService: TokenService) + { } + + ngOnInit(): void { + if (!this._tokenService.getTokenFromSessionStorage()) { + this._router.navigate(['/login']); + return; + } + + this._userService.getUserFromSessionStorageRequest().subscribe( + (result: object) => { + console.log('bruh'); + const user = result as User; + if (!user.roles.map(x => x.name).includes(AppConstants.ADMIN_ROLE_NAME)) { + this._router.navigate(['/login']); + } + }, + (err: HttpErrorResponse) => { + this._router.navigate(['/login']); + } + ); + + this.languageForm = this._fb.group({ + languageCreate: new FormControl(''), + updateLanguageOldName: new FormControl(''), + updateLanguageNewName: new FormControl(''), + deleteLanguageName: new FormControl('') + }); + + this.loadAvailableLanguages(); + this.loadAvailableTechnologies(); + } + + // Navigation + + backToProfile(): void { + this._router.navigate(['/profile/' + this._tokenService.getUsernameFromSessionStorageToken()]); + } + + backToFeed(): void { + this._router.navigate(['/']); + } + + logout(): void { + this._tokenService.logoutUserFromSessionStorage(); + this._router.navigate(['/login']); + } + + // Language modifying + + toggleLanguages(): void { + this.showLanguages = !this.showLanguages; + } + + submitLanguages(): void { + this.tryCreateLanguage(); + this.tryUpdateLanguage(); + this.tryDeleteLanguage(); + } + + private tryCreateLanguage(): void { + const languageCreate: string = this.languageForm.get('languageCreate')?.value; + + if (languageCreate !== '' && languageCreate !== null) { + this._languageService.createLanguageWithSessionStorageRequest(languageCreate.trim()).subscribe( + (result: object) => { + this.languageModifiedSuccess('Successfully updated languages!'); + }, + (err: HttpErrorResponse) => { + this._errorBar.showError(err); + } + ); + } + } + + private tryUpdateLanguage(): void { + const updateLanguageOldName: string = this.languageForm.get('updateLanguageOldName')?.value; + const updateLanguageNewName: string = this.languageForm.get('updateLanguageNewName')?.value; + + if (updateLanguageOldName !== '' && updateLanguageOldName !== null && updateLanguageNewName !== '' && updateLanguageNewName !== null) { + const langId = this.availableLanguages.filter(x => x.name === updateLanguageOldName.trim())[0].id; + + this._languageService.putLanguageWithSessionStorageRequest(langId, updateLanguageNewName.trim()).subscribe( + (result: object) => { + this.languageModifiedSuccess('Successfully updated languages!'); + }, + (err: HttpErrorResponse) => { + this._errorBar.showError(err); + } + ); + } + } + + private tryDeleteLanguage(): void { + const deleteLanguageName: string = this.languageForm.get('deleteLanguageName')?.value; + + if (deleteLanguageName !== '' && deleteLanguageName !== null) { + const langId = this.availableLanguages.filter(x => x.name === deleteLanguageName.trim())[0].id; + + console.log(langId); + this._languageService.deleteLanguageWithSessionStorageRequest(langId).subscribe( + (result: object) => { + this.languageModifiedSuccess('Successfully deleted language!'); + }, + (err: HttpErrorResponse) => { + this._errorBar.showError(err); + } + ); + } + } + + private languageModifiedSuccess(successMsg: string): void { + this._successBar.showMsg(successMsg); + this.loadAvailableLanguages(); + this.languageForm.reset(); + } + + private loadAvailableLanguages(): void { + this._languageService.getAllLanguagesWithSessionStorageRequest().subscribe( + (result: object) => { + this.availableLanguages = result as Language[]; + } + ); + } + + // Technology modifying + + private loadAvailableTechnologies(): void { + this._technologyService.getAllTechnologiesWithSessionStorageRequest().subscribe( + (result: object) => { + this.availableTechnologies = result as Technology[]; + } + ); + } + + toggleTechnologies(): void { + this.showTechnologies = !this.showTechnologies; + } +} diff --git a/src/DevHive.Angular/src/app/components/profile/profile.component.html b/src/DevHive.Angular/src/app/components/profile/profile.component.html index 9cb4dd2..8242b05 100644 --- a/src/DevHive.Angular/src/app/components/profile/profile.component.html +++ b/src/DevHive.Angular/src/app/components/profile/profile.component.html @@ -4,6 +4,7 @@
diff --git a/src/DevHive.Angular/src/app/components/profile/profile.component.ts b/src/DevHive.Angular/src/app/components/profile/profile.component.ts index 5dd965e..2502b48 100644 --- a/src/DevHive.Angular/src/app/components/profile/profile.component.ts +++ b/src/DevHive.Angular/src/app/components/profile/profile.component.ts @@ -19,6 +19,7 @@ import { TokenService } from 'src/app/services/token.service'; export class ProfileComponent implements OnInit { private _urlUsername: string; public loggedInUser = false; + public isAdminUser = false; public dataArrived = false; public user: User; public userPosts: Post[]; @@ -99,6 +100,7 @@ export class ProfileComponent implements OnInit { this.loggedInUser = true; } this.dataArrived = true; + this.isAdminUser = this.user.roles.map(x => x.name).includes(AppConstants.ADMIN_ROLE_NAME); }, (err: HttpErrorResponse) => { this.logout(); @@ -114,6 +116,10 @@ export class ProfileComponent implements OnInit { this._router.navigate(['/']); } + navigateToAdminPanel(): void { + this._router.navigate(['/admin-panel']); + } + navigateToSettings(): void { this._router.navigate([this._router.url + '/settings']); } diff --git a/src/DevHive.Angular/src/app/services/language.service.ts b/src/DevHive.Angular/src/app/services/language.service.ts index 49be537..15e241f 100644 --- a/src/DevHive.Angular/src/app/services/language.service.ts +++ b/src/DevHive.Angular/src/app/services/language.service.ts @@ -15,14 +15,42 @@ export class LanguageService { /* Requests from session storage */ + createLanguageWithSessionStorageRequest(name: string): Observable { + const token = this._tokenService.getTokenFromSessionStorage(); + + return this.createLanguageRequest(name, token); + } + getAllLanguagesWithSessionStorageRequest(): Observable { const token = this._tokenService.getTokenFromSessionStorage(); return this.getAllLanguagesRequest(token); } + putLanguageWithSessionStorageRequest(langId: Guid, newName: string): Observable { + const token = this._tokenService.getTokenFromSessionStorage(); + + return this.putLanguageRequest(token, langId, newName); + } + + deleteLanguageWithSessionStorageRequest(langId: Guid): Observable { + const token = this._tokenService.getTokenFromSessionStorage(); + + return this.deleteLanguageRequest(token, langId); + } + /* Language requests */ + createLanguageRequest(name: string, authToken: string): Observable { + const body = { + name: name + }; + const options = { + headers: new HttpHeaders().set('Authorization', 'Bearer ' + authToken) + }; + return this._http.post(AppConstants.API_LANGUAGE_URL, body, options); + } + getLanguageRequest(langId: Guid): Observable { const options = { params: new HttpParams().set('Id', langId.toString()), @@ -63,4 +91,23 @@ export class LanguageService { } }); } + + putLanguageRequest(authToken: string, langId: Guid, newName: string): Observable { + const body = { + name: newName + }; + const options = { + params: new HttpParams().set('Id', langId.toString()), + headers: new HttpHeaders().set('Authorization', 'Bearer ' + authToken) + }; + return this._http.put(AppConstants.API_LANGUAGE_URL, body, options); + } + + deleteLanguageRequest(authToken: string, langId: Guid): Observable { + const options = { + params: new HttpParams().set('Id', langId.toString()), + headers: new HttpHeaders().set('Authorization', 'Bearer ' + authToken) + }; + return this._http.delete(AppConstants.API_LANGUAGE_URL, options); + } } -- cgit v1.2.3