Added series card implementation. Added a mock cover to help visualize style changes. Implemented ability to create a new library without validation errors. Fixed a bug in directory picker that caused selected folders to not export the full path.
This commit is contained in:
parent
fe5ec2f032
commit
1816b6c68d
20 changed files with 235 additions and 31 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
export interface Volume {
|
export interface Volume {
|
||||||
id: number;
|
id: number;
|
||||||
number: string;
|
number: number;
|
||||||
|
name: string;
|
||||||
files: Array<string>;
|
files: Array<string>;
|
||||||
coverImage: string;
|
coverImage: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,4 +37,8 @@ export class LibraryService {
|
||||||
return this.httpClient.post(this.baseUrl + 'library/scan?libraryId=' + libraryId, {});
|
return this.httpClient.post(this.baseUrl + 'library/scan?libraryId=' + libraryId, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create(model: {name: string, type: number, folders: string[]}) {
|
||||||
|
return this.httpClient.post(this.baseUrl + 'library/create', model);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,9 @@ export class DirectoryPickerComponent implements OnInit {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.modal.close({success: true, folderPath: folderName});
|
const fullPath = (this.routeStack.items.join('\\') + '\\' + folderName).replace('\\\\', '\\');
|
||||||
|
|
||||||
|
this.modal.close({success: true, folderPath: fullPath});
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
|
|
|
||||||
|
|
@ -1 +1,37 @@
|
||||||
<p>library-editor-modal works!</p>
|
|
||||||
|
<form [formGroup]="libraryForm" (ngSubmit)="submitLibrary()">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title" id="modal-basic-title">New Library</h4>
|
||||||
|
<button type="button" class="close" aria-label="Close" (click)="close()">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="library-name">Name</label>
|
||||||
|
<input id="library-name" class="form-control" formControlName="name" type="text">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="library-type">Type</label>
|
||||||
|
<select class="form-control" id="library-type" formControlName="type">
|
||||||
|
<option [value]="0">Manga</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<h4>Folders:</h4>
|
||||||
|
<button class="btn btn-primary" (click)="openDirectoryPicker()">Add Folder</button>
|
||||||
|
<div class="list-group">
|
||||||
|
<li class="list-group-item" *ngFor="let folder of selectedFolders; let i = index">
|
||||||
|
{{folder}}
|
||||||
|
<!-- TODO: Implement ability to remove folders added-->
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-light" (click)="reset()">Reset</button>
|
||||||
|
<button type="button" class="btn btn-secondary" (click)="close()">Cancel</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { LibraryService } from 'src/app/_services/library.service';
|
||||||
|
import { DirectoryPickerComponent, DirectoryPickerResult } from '../directory-picker/directory-picker.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-library-editor-modal',
|
selector: 'app-library-editor-modal',
|
||||||
|
|
@ -7,9 +11,45 @@ import { Component, OnInit } from '@angular/core';
|
||||||
})
|
})
|
||||||
export class LibraryEditorModalComponent implements OnInit {
|
export class LibraryEditorModalComponent implements OnInit {
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
libraryForm: FormGroup = new FormGroup({
|
||||||
|
name: new FormControl('', [Validators.required]),
|
||||||
|
type: new FormControl(0, [Validators.required])
|
||||||
|
});
|
||||||
|
|
||||||
|
selectedFolders: string[] = [];
|
||||||
|
|
||||||
|
constructor(private modalService: NgbModal, private libraryService: LibraryService, public modal: NgbActiveModal) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
submitLibrary() {
|
||||||
|
const model = this.libraryForm.value;
|
||||||
|
model.folders = this.selectedFolders;
|
||||||
|
console.log('Creating library with: ', model);
|
||||||
|
// this.libraryService.create(model).subscribe(() => {
|
||||||
|
// this.close(true);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
close(returnVal= false) {
|
||||||
|
this.modal.close(returnVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
openDirectoryPicker() {
|
||||||
|
const modalRef = this.modalService.open(DirectoryPickerComponent);
|
||||||
|
modalRef.closed.subscribe((closeResult: DirectoryPickerResult) => {
|
||||||
|
if (closeResult.success) {
|
||||||
|
this.selectedFolders.push(closeResult.folderPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { LibraryEditorModalComponent } from './_modals/library-editor-modal/libr
|
||||||
import { SharedModule } from '../shared/shared.module';
|
import { SharedModule } from '../shared/shared.module';
|
||||||
import { LibraryAccessModalComponent } from './_modals/library-access-modal/library-access-modal.component';
|
import { LibraryAccessModalComponent } from './_modals/library-access-modal/library-access-modal.component';
|
||||||
import { DirectoryPickerComponent } from './_modals/directory-picker/directory-picker.component';
|
import { DirectoryPickerComponent } from './_modals/directory-picker/directory-picker.component';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -25,9 +25,10 @@ import { FormsModule } from '@angular/forms';
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
AdminRoutingModule,
|
AdminRoutingModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
FormsModule,
|
||||||
NgbNavModule,
|
NgbNavModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
FormsModule
|
|
||||||
],
|
],
|
||||||
providers: []
|
providers: []
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>Title (Manga/Recently Added)</h2>
|
<h2>Title (Manga/Recently Added)</h2>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-2" *ngFor="let manga of series">
|
<div class="col-sm-auto" *ngFor="let manga of series">
|
||||||
<app-card-item [title]="manga.name" (clicked)="seriesClicked(manga)"></app-card-item>
|
<app-series-card [data]="manga" [libraryId]="libraryId"></app-series-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ng-container *ngIf="series.length === 0">
|
<ng-container *ngIf="series.length === 0">
|
||||||
<!-- Put a cricket here -->
|
<!-- TODO: Put a loader here -->
|
||||||
Nothing here....
|
Nothing here....
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
|
|
||||||
<h2>Libraries</h2>
|
<h2>Libraries</h2>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 col-md-4 col-lg-2" *ngFor="let library of libraries">
|
<div class="col-sm-auto" *ngFor="let library of libraries">
|
||||||
<app-library-card [data]="library"></app-library-card>
|
<app-library-card [data]="library"></app-library-card>
|
||||||
<!-- <app-card-item [imageUrl]="library.coverImage" [title]="library.name" (clicked)="handleNavigation($event, library)" [actions]="actions" [entity]="library"></app-card-item> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -25,6 +25,11 @@ export class LibraryComponent implements OnInit {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.libraryService.getLibrariesForMember(this.user.username).subscribe(libraries => {
|
this.libraryService.getLibrariesForMember(this.user.username).subscribe(libraries => {
|
||||||
this.libraries = libraries;
|
this.libraries = libraries;
|
||||||
|
if (this.libraries.length > 0) {
|
||||||
|
// TODO: Remove this debug code
|
||||||
|
console.warn('Warning, debug code is being used!');
|
||||||
|
this.libraries[0].coverImage = '/assets/images/mock-cover.jpg';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<!-- TODO: Put SignalR notification button dropdown here. -->
|
<!-- TODO: Put SignalR notification button dropdown here. -->
|
||||||
|
|
||||||
<div ngbDropdown class=" nav-item dropdown" *ngIf="(accountService.currentUser$ | async) as user" dropdown>
|
<div ngbDropdown class=" nav-item dropdown" *ngIf="(accountService.currentUser$ | async) as user" dropdown>
|
||||||
<button class="btn btn-outline-primary" ngbDropdownToggle>{{user.username | titlecase}}</button>
|
<button class="btn btn-outline-secondary" ngbDropdownToggle>{{user.username | titlecase}}</button>
|
||||||
<div ngbDropdownMenu >
|
<div ngbDropdownMenu >
|
||||||
<button ngbDropdownItem routerLink="/admin/dashboard" *ngIf="user.roles.includes('Admin')">Server Settings</button>
|
<button ngbDropdownItem routerLink="/admin/dashboard" *ngIf="user.roles.includes('Admin')">Server Settings</button>
|
||||||
<button ngbDropdownItem (click)="logout()">Logout</button>
|
<button ngbDropdownItem (click)="logout()">Logout</button>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<div class="container" *ngIf="series !== undefined">
|
<div class="container" *ngIf="series !== undefined">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-2">
|
<div class="col-md-4 col-mr-auto">
|
||||||
<app-card-item [imageUrl]="series.coverImage === null ? 'assets/images/image-placeholder.jpg' : series.coverImage"></app-card-item>
|
<app-card-item [imageUrl]="series.coverImage === null ? 'assets/images/image-placeholder.jpg' : series.coverImage"></app-card-item>
|
||||||
<button class="btn btn-primary">Read</button>
|
<button class="btn btn-primary">Read</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-10">
|
<div class="col-md-8">
|
||||||
<h2>{{series.name | titlecase}}</h2>
|
<h2>{{series.name | titlecase}}</h2>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<ngb-rating></ngb-rating>
|
<ngb-rating></ngb-rating>
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<h4 class="mt-3">Volumes</h4>
|
<h4 class="mt-3">Volumes</h4>
|
||||||
<div class="row mt-3">
|
<div class="row mt-3">
|
||||||
<div class="col-md-2" *ngFor="let volume of volumes">
|
<div class="col-sm-auto" *ngFor="let volume of volumes">
|
||||||
<app-card-item [entity]="volume" [title]="'Volume ' + volume.number" (click)="openVolume(volume)"></app-card-item>
|
<app-card-item [entity]="volume" [title]="'Volume ' + volume.number" (click)="openVolume(volume)"></app-card-item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,22 @@
|
||||||
<img (click)="handleClick()" class="card-img-top" src="{{isNullOrEmpty(imageUrl) ? placeholderImage : imageUrl}}" alt="{{title}}">
|
<img (click)="handleClick()" class="card-img-top" src="{{isNullOrEmpty(imageUrl) ? placeholderImage : imageUrl}}" alt="{{title}}">
|
||||||
|
|
||||||
<div class="card-body text-center" *ngIf="title.length > 0 || actions.length > 0">
|
<div class="card-body text-center" *ngIf="title.length > 0 || actions.length > 0">
|
||||||
<h5 class="card-title" (click)="handleClick()">{{title}}</h5>
|
|
||||||
<ng-container *ngIf="actions.length > 0">
|
<span class="card-title" (click)="handleClick()">
|
||||||
<div class="col">
|
{{title}}
|
||||||
<div ngbDropdown class="d-inline-block">
|
</span>
|
||||||
|
<div class="pull-right">
|
||||||
|
<ng-container *ngIf="actions.length > 0">
|
||||||
|
<div ngbDropdown container="body" class="d-inline-block">
|
||||||
<button class="btn" id="actions-{{title}}" ngbDropdownToggle><i class="fa fa-ellipsis-v" aria-hidden="true"></i></button>
|
<button class="btn" id="actions-{{title}}" ngbDropdownToggle><i class="fa fa-ellipsis-v" aria-hidden="true"></i></button>
|
||||||
<div ngbDropdownMenu attr.aria-labelledby="actions-{{title}}">
|
<div ngbDropdownMenu attr.aria-labelledby="actions-{{title}}">
|
||||||
<button ngbDropdownItem *ngFor="let action of actions" (click)="performAction($event, action)">{{action.title}}</button>
|
<button ngbDropdownItem *ngFor="let action of actions" (click)="performAction($event, action)">{{action.title}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</ng-container>
|
||||||
</ng-container>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1,7 +1,15 @@
|
||||||
.card {
|
.card {
|
||||||
margin: 5px;
|
margin: 10px;
|
||||||
max-width: 130px;
|
// max-width: 130px;
|
||||||
max-height: 195px;
|
// max-height: 195px;
|
||||||
|
max-width: 160px;
|
||||||
|
max-height: 320px;
|
||||||
|
|
||||||
|
// 370 x 210 roughly
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-body {
|
.card-body {
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ export class CardItemComponent implements OnInit {
|
||||||
|
|
||||||
@Input() imageUrl = '';
|
@Input() imageUrl = '';
|
||||||
@Input() title = '';
|
@Input() title = '';
|
||||||
@Input() actions: CardItemAction[] = []; // TODO: Create a factory that generates actions based on if admin, etc. for each card type.
|
@Input() actions: CardItemAction[] = [];
|
||||||
@Input() entity: any; // This is the entity we are representing. It will be returned if an action is executed.
|
@Input() entity: any; // This is the entity we are representing. It will be returned if an action is executed.
|
||||||
@Output() clicked = new EventEmitter<string>();
|
@Output() clicked = new EventEmitter<string>();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,11 +40,19 @@ export class LibraryCardComponent implements OnInit, OnChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
generateActions() {
|
generateActions() {
|
||||||
this.actions = [];
|
this.actions = [
|
||||||
|
{
|
||||||
|
title: 'Mark as Read',
|
||||||
|
callback: () => this.markAsRead
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Mark as Unread',
|
||||||
|
callback: () => this.markAsUnread
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
if (this.isAdmin) {
|
if (this.isAdmin) {
|
||||||
this.actions.push({title: 'Scan Library', callback: (data: Library) => {
|
this.actions.push({title: 'Scan Library', callback: (data: Library) => {
|
||||||
console.log('You tried to scan library: ' + data.name);
|
|
||||||
this.libraryService.scan(data?.id).subscribe((res: any) => {
|
this.libraryService.scan(data?.id).subscribe((res: any) => {
|
||||||
this.toastr.success('Scan started for ' + data.name);
|
this.toastr.success('Scan started for ' + data.name);
|
||||||
});
|
});
|
||||||
|
|
@ -52,6 +60,14 @@ export class LibraryCardComponent implements OnInit, OnChanges {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
markAsUnread(library: any) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsRead(library: any) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
handleClick() {
|
handleClick() {
|
||||||
this.clicked.emit(this.data);
|
this.clicked.emit(this.data);
|
||||||
this.router.navigate(['library', this.data?.id]);
|
this.router.navigate(['library', this.data?.id]);
|
||||||
|
|
|
||||||
3
src/app/shared/series-card/series-card.component.html
Normal file
3
src/app/shared/series-card/series-card.component.html
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<ng-container *ngIf="data !== undefined">
|
||||||
|
<app-card-item [title]="data.name" [actions]="actions" [imageUrl]="data.coverImage" [entity]="data" (clicked)="handleClick()"></app-card-item>
|
||||||
|
</ng-container>
|
||||||
0
src/app/shared/series-card/series-card.component.scss
Normal file
0
src/app/shared/series-card/series-card.component.scss
Normal file
76
src/app/shared/series-card/series-card.component.ts
Normal file
76
src/app/shared/series-card/series-card.component.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { ToastrService } from 'ngx-toastr';
|
||||||
|
import { take } from 'rxjs/internal/operators/take';
|
||||||
|
import { Series } from 'src/app/_models/series';
|
||||||
|
import { AccountService } from 'src/app/_services/account.service';
|
||||||
|
import { SeriesService } from 'src/app/_services/series.service';
|
||||||
|
import { CardItemAction } from '../card-item/card-item.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-series-card',
|
||||||
|
templateUrl: './series-card.component.html',
|
||||||
|
styleUrls: ['./series-card.component.scss']
|
||||||
|
})
|
||||||
|
export class SeriesCardComponent implements OnInit {
|
||||||
|
@Input() data: Series | undefined;
|
||||||
|
@Input() libraryId = 0;
|
||||||
|
@Output() clicked = new EventEmitter<Series>();
|
||||||
|
|
||||||
|
isAdmin = false;
|
||||||
|
actions: CardItemAction[] = [];
|
||||||
|
|
||||||
|
constructor(private accountService: AccountService, private router: Router,
|
||||||
|
private seriesService: SeriesService, private toastr: ToastrService) {
|
||||||
|
this.accountService.currentUser$.pipe(take(1)).subscribe(user => {
|
||||||
|
if (user) {
|
||||||
|
this.isAdmin = this.accountService.hasAdminRole(user);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: any) {
|
||||||
|
if (this.data) {
|
||||||
|
this.generateActions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
generateActions() {
|
||||||
|
this.actions = [
|
||||||
|
{
|
||||||
|
title: 'Mark as Read',
|
||||||
|
callback: () => this.markAsRead
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Mark as Unread',
|
||||||
|
callback: () => this.markAsUnread
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
if (this.isAdmin) {
|
||||||
|
// this.actions.push({title: 'Scan Library', callback: (data: Library) => {
|
||||||
|
// this.libraryService.scan(this.libraryId).subscribe((res: any) => {
|
||||||
|
// this.toastr.success('Scan started for ' + data.name);
|
||||||
|
// });
|
||||||
|
// }});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsUnread(series: any) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsRead(series: any) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick() {
|
||||||
|
this.clicked.emit(this.data);
|
||||||
|
this.router.navigate(['library', this.libraryId, 'series', this.data?.id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -5,11 +5,17 @@ import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { CardItemComponent } from './card-item/card-item.component';
|
import { CardItemComponent } from './card-item/card-item.component';
|
||||||
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { LibraryCardComponent } from './library-card/library-card.component';
|
import { LibraryCardComponent } from './library-card/library-card.component';
|
||||||
|
import { SeriesCardComponent } from './series-card/series-card.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [RegisterMemberComponent, CardItemComponent, LibraryCardComponent],
|
declarations: [
|
||||||
|
RegisterMemberComponent,
|
||||||
|
CardItemComponent,
|
||||||
|
LibraryCardComponent,
|
||||||
|
SeriesCardComponent
|
||||||
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
|
|
@ -18,7 +24,8 @@ import { LibraryCardComponent } from './library-card/library-card.component';
|
||||||
exports: [
|
exports: [
|
||||||
RegisterMemberComponent,
|
RegisterMemberComponent,
|
||||||
CardItemComponent,
|
CardItemComponent,
|
||||||
LibraryCardComponent
|
LibraryCardComponent,
|
||||||
|
SeriesCardComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SharedModule { }
|
export class SharedModule { }
|
||||||
|
|
|
||||||
BIN
src/assets/images/mock-cover.jpg
Normal file
BIN
src/assets/images/mock-cover.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Loading…
Add table
Add a link
Reference in a new issue