From 8865c121d229f80bb092fde989ec7c4f90169634 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Thu, 31 Dec 2020 15:14:32 -0600 Subject: [PATCH] Added ability to have actions on cards. --- src/app/_guards/admin.guard.ts | 2 +- src/app/_services/account.service.ts | 4 ++++ src/app/_services/member.service.ts | 2 +- src/app/app-routing.module.ts | 4 +++- .../library-detail.component.html | 4 ++-- .../library-detail/library-detail.component.ts | 4 ++++ src/app/library/library.component.html | 2 +- src/app/library/library.component.ts | 10 +++++++++- .../series-detail/series-detail.component.html | 6 +++--- .../series-detail/series-detail.component.ts | 3 +++ .../shared/card-item/card-item.component.html | 16 +++++++++++++--- .../shared/card-item/card-item.component.scss | 4 ++++ .../shared/card-item/card-item.component.ts | 18 +++++++++++++----- src/app/shared/shared.module.ts | 4 +++- 14 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/app/_guards/admin.guard.ts b/src/app/_guards/admin.guard.ts index 2297e381c..d59b8643c 100644 --- a/src/app/_guards/admin.guard.ts +++ b/src/app/_guards/admin.guard.ts @@ -16,7 +16,7 @@ export class AdminGuard implements CanActivate { // this automaticallys subs due to being router guard return this.accountService.currentUser$.pipe( map((user: User) => { - if (user && user.roles.includes('Admin')) { + if (this.accountService.hasAdminRole(user)) { return true; } diff --git a/src/app/_services/account.service.ts b/src/app/_services/account.service.ts index dc6449c6e..9da467d08 100644 --- a/src/app/_services/account.service.ts +++ b/src/app/_services/account.service.ts @@ -21,6 +21,10 @@ export class AccountService { constructor(private httpClient: HttpClient) { } + hasAdminRole(user: User) { + return user && user.roles.includes('Admin'); + } + login(model: any): Observable { return this.httpClient.post(this.baseUrl + 'account/login', model).pipe( map((response: User) => { diff --git a/src/app/_services/member.service.ts b/src/app/_services/member.service.ts index 08eee8bfe..32d219920 100644 --- a/src/app/_services/member.service.ts +++ b/src/app/_services/member.service.ts @@ -21,7 +21,7 @@ export class MemberService { } updatePassword(newPassword: string) { - // TODO: Implement update password (use JWT to assume role) + // TODO: Implement update password } deleteMember(username: string) { diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index c0d3127d9..9b1705767 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -3,6 +3,7 @@ import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { LibraryDetailComponent } from './library-detail/library-detail.component'; import { LibraryComponent } from './library/library.component'; +import { SeriesDetailComponent } from './series-detail/series-detail.component'; const routes: Routes = [ {path: '', component: HomeComponent}, @@ -11,7 +12,8 @@ const routes: Routes = [ loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }, {path: 'library', component: LibraryComponent}, - {path: 'library/:id', component: LibraryDetailComponent}, + {path: 'library/:id', component: LibraryDetailComponent}, // NOTE: Should I put a guard up to prevent unauthorized access to libraries and series? + {path: 'series/:id', component: SeriesDetailComponent}, {path: '**', component: HomeComponent, pathMatch: 'full'} ]; diff --git a/src/app/library-detail/library-detail.component.html b/src/app/library-detail/library-detail.component.html index dfb0e8e41..237312e99 100644 --- a/src/app/library-detail/library-detail.component.html +++ b/src/app/library-detail/library-detail.component.html @@ -1,6 +1,6 @@

Title (Manga/Recently Added)

-
- +
+
\ No newline at end of file diff --git a/src/app/library-detail/library-detail.component.ts b/src/app/library-detail/library-detail.component.ts index fd4625b9b..43c3d5460 100644 --- a/src/app/library-detail/library-detail.component.ts +++ b/src/app/library-detail/library-detail.component.ts @@ -31,4 +31,8 @@ export class LibraryDetailComponent implements OnInit { ngOnInit(): void { } + seriesClicked(series: Series) { + this.router.navigateByUrl('/series/' + series.id); + } + } diff --git a/src/app/library/library.component.html b/src/app/library/library.component.html index f618c2e64..666f33e34 100644 --- a/src/app/library/library.component.html +++ b/src/app/library/library.component.html @@ -2,6 +2,6 @@

Libraries

- +
\ No newline at end of file diff --git a/src/app/library/library.component.ts b/src/app/library/library.component.ts index 4b2a454ef..c4f027c73 100644 --- a/src/app/library/library.component.ts +++ b/src/app/library/library.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { take } from 'rxjs/operators'; +import { CardItemAction } from '../shared/card-item/card-item.component'; import { Library } from '../_models/library'; import { User } from '../_models/user'; import { AccountService } from '../_services/account.service'; @@ -16,13 +17,20 @@ export class LibraryComponent implements OnInit { user: User | undefined; libraries: Library[] = []; + actions: CardItemAction[] = []; constructor(public accountService: AccountService, private libraryService: LibraryService, private router: Router) { } ngOnInit(): void { this.accountService.currentUser$.pipe(take(1)).subscribe(user => { this.user = user; - console.log('user: ', this.user); + if (this.accountService.hasAdminRole(user)) { + this.actions = [ + {title: 'Scan Library', callback: (data: Library) => { + console.log('You tried to scan library: ' + data.name); + }} + ]; + } this.libraryService.getLibrariesForMember(this.user.username).subscribe(libraries => { this.libraries = libraries; console.log('Libraries: ', this.libraries); diff --git a/src/app/series-detail/series-detail.component.html b/src/app/series-detail/series-detail.component.html index 2416b8c0a..4ad9e0f2b 100644 --- a/src/app/series-detail/series-detail.component.html +++ b/src/app/series-detail/series-detail.component.html @@ -1,8 +1,8 @@ -

title

@@ -17,4 +17,4 @@ Volumes here - --> \ No newline at end of file + \ No newline at end of file diff --git a/src/app/series-detail/series-detail.component.ts b/src/app/series-detail/series-detail.component.ts index 54603840e..93df5173a 100644 --- a/src/app/series-detail/series-detail.component.ts +++ b/src/app/series-detail/series-detail.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { Series } from '../_models/series'; @Component({ selector: 'app-series-detail', @@ -7,6 +8,8 @@ import { Component, OnInit } from '@angular/core'; }) export class SeriesDetailComponent implements OnInit { + series: Series | undefined; + constructor() { } ngOnInit(): void { diff --git a/src/app/shared/card-item/card-item.component.html b/src/app/shared/card-item/card-item.component.html index bd8c0e237..41523ea92 100644 --- a/src/app/shared/card-item/card-item.component.html +++ b/src/app/shared/card-item/card-item.component.html @@ -1,7 +1,17 @@ -
- {{title}} +
+ {{title}}
-
{{title}}
+
{{title}}
+ +
+
+ +
+ +
+
+
+
\ No newline at end of file diff --git a/src/app/shared/card-item/card-item.component.scss b/src/app/shared/card-item/card-item.component.scss index a6b9c3588..9987ed9cc 100644 --- a/src/app/shared/card-item/card-item.component.scss +++ b/src/app/shared/card-item/card-item.component.scss @@ -6,4 +6,8 @@ .card-body { padding: 5px !important; +} + +.dropdown-toggle:after { + content: none !important; } \ No newline at end of file diff --git a/src/app/shared/card-item/card-item.component.ts b/src/app/shared/card-item/card-item.component.ts index 479765d76..ec10d3f28 100644 --- a/src/app/shared/card-item/card-item.component.ts +++ b/src/app/shared/card-item/card-item.component.ts @@ -1,8 +1,9 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -export interface CardItemTitle { + +export interface CardItemAction { title: string; - linkUrl: string; + callback: (data: any) => void; } @Component({ @@ -14,15 +15,15 @@ export class CardItemComponent implements OnInit { @Input() imageUrl = ''; @Input() title = ''; + @Input() actions: CardItemAction[] = []; + @Input() entity: any; // This is the entity we are representing. It will be returned if an action is executed. @Output() clicked = new EventEmitter(); - placeholderImage = 'assets/images/image-placeholder.jpg'; //../../.. + placeholderImage = 'assets/images/image-placeholder.jpg'; constructor() { } ngOnInit(): void { - console.log('card item'); - console.log('imageUrl: ', this.imageUrl); } handleClick() { @@ -33,4 +34,11 @@ export class CardItemComponent implements OnInit { return val === null || val === undefined || val === ''; } + performAction(event: any, action: CardItemAction) { + event.stopPropagation(); + if (typeof action.callback === 'function') { + action.callback(this.entity); + } + } + } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index f8cc3fc44..01a2b702f 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common'; import { RegisterMemberComponent } from './register-member/register-member.component'; import { ReactiveFormsModule } from '@angular/forms'; import { CardItemComponent } from './card-item/card-item.component'; +import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; @@ -10,7 +11,8 @@ import { CardItemComponent } from './card-item/card-item.component'; declarations: [RegisterMemberComponent, CardItemComponent], imports: [ CommonModule, - ReactiveFormsModule + ReactiveFormsModule, + NgbDropdownModule ], exports: [ RegisterMemberComponent,