mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-05-24 00:52:23 -04:00
Implemented Publication Status in SeriesMetadata and the ability to filter it. (#915)
This commit is contained in:
parent
f8e0fb8a27
commit
2fbcf203aa
@ -93,6 +93,27 @@ public class MetadataController : BaseApiController
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches all publication status' from the instance
|
||||
/// </summary>
|
||||
/// <param name="libraryIds">String separated libraryIds or null for all publication status</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("publication-status")]
|
||||
public async Task<ActionResult<IList<AgeRatingDto>>> GetAllPublicationStatus(string? libraryIds)
|
||||
{
|
||||
var ids = libraryIds?.Split(",").Select(int.Parse).ToList();
|
||||
if (ids != null && ids.Count > 0)
|
||||
{
|
||||
return Ok(await _unitOfWork.SeriesRepository.GetAllPublicationStatusesDtosForLibrariesAsync(ids));
|
||||
}
|
||||
|
||||
return Ok(Enum.GetValues<PublicationStatus>().Select(t => new PublicationStatusDto()
|
||||
{
|
||||
Title = t.ToDescription(),
|
||||
Value = t
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches all age ratings from the instance
|
||||
/// </summary>
|
||||
|
@ -53,7 +53,8 @@ public class OpdsController : BaseApiController
|
||||
CollectionTags = new List<int>(),
|
||||
CoverArtist = new List<int>(),
|
||||
ReadStatus = new ReadStatus(),
|
||||
SortOptions = null
|
||||
SortOptions = null,
|
||||
PublicationStatus = new List<PublicationStatus>()
|
||||
};
|
||||
private readonly ChapterSortComparer _chapterSortComparer = new ChapterSortComparer();
|
||||
|
||||
|
@ -70,6 +70,14 @@ namespace API.DTOs
|
||||
/// Language for the Chapter/Issue
|
||||
/// </summary>
|
||||
public string Language { get; set; }
|
||||
/// <summary>
|
||||
/// Number in the TotalCount of issues
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
/// <summary>
|
||||
/// Total number of issues for the series
|
||||
/// </summary>
|
||||
public int TotalCount { get; set; }
|
||||
public ICollection<PersonDto> Writers { get; set; } = new List<PersonDto>();
|
||||
public ICollection<PersonDto> Penciller { get; set; } = new List<PersonDto>();
|
||||
public ICollection<PersonDto> Inker { get; set; } = new List<PersonDto>();
|
||||
|
@ -89,6 +89,10 @@ namespace API.DTOs.Filtering
|
||||
/// Languages (ISO 639-1 code) to filter by. Empty list will return everything back
|
||||
/// </summary>
|
||||
public IList<string> Languages { get; init; } = new List<string>();
|
||||
/// <summary>
|
||||
/// Publication statuses to filter by. Empty list will return everything back
|
||||
/// </summary>
|
||||
public IList<PublicationStatus> PublicationStatus { get; init; } = new List<PublicationStatus>();
|
||||
|
||||
}
|
||||
}
|
||||
|
9
API/DTOs/Metadata/PublicationStatusDto.cs
Normal file
9
API/DTOs/Metadata/PublicationStatusDto.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using API.Entities.Enums;
|
||||
|
||||
namespace API.DTOs.Metadata;
|
||||
|
||||
public class PublicationStatusDto
|
||||
{
|
||||
public PublicationStatus Value { get; set; }
|
||||
public string Title { get; set; }
|
||||
}
|
@ -43,6 +43,18 @@ namespace API.DTOs
|
||||
/// Language of the content (ISO 639-1 code)
|
||||
/// </summary>
|
||||
public string Language { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// Number in the TotalCount of issues
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
/// <summary>
|
||||
/// Total number of issues for the series
|
||||
/// </summary>
|
||||
public int TotalCount { get; set; }
|
||||
/// <summary>
|
||||
/// Publication status of the Series
|
||||
/// </summary>
|
||||
public PublicationStatus PublicationStatus { get; set; }
|
||||
|
||||
public int SeriesId { get; set; }
|
||||
}
|
||||
|
@ -8,13 +8,17 @@ namespace API.Data.Metadata
|
||||
/// <summary>
|
||||
/// A representation of a ComicInfo.xml file
|
||||
/// </summary>
|
||||
/// <remarks>See reference of the loose spec here: https://github.com/Kussie/ComicInfoStandard/blob/main/ComicInfo.xsd</remarks>
|
||||
/// <remarks>See reference of the loose spec here: https://anansi-project.github.io/docs/comicinfo/documentation</remarks>
|
||||
public class ComicInfo
|
||||
{
|
||||
public string Summary { get; set; } = string.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Series { get; set; } = string.Empty;
|
||||
public string Number { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// The total number of items in the series.
|
||||
/// </summary>
|
||||
public int Count { get; set; } = 0;
|
||||
public string Volume { get; set; } = string.Empty;
|
||||
public string Notes { get; set; } = string.Empty;
|
||||
public string Genre { get; set; } = string.Empty;
|
||||
|
1345
API/Data/Migrations/20220108200822_CountMetadata.Designer.cs
generated
Normal file
1345
API/Data/Migrations/20220108200822_CountMetadata.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
37
API/Data/Migrations/20220108200822_CountMetadata.cs
Normal file
37
API/Data/Migrations/20220108200822_CountMetadata.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace API.Data.Migrations
|
||||
{
|
||||
public partial class CountMetadata : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Count",
|
||||
table: "SeriesMetadata",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Count",
|
||||
table: "Chapter",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Count",
|
||||
table: "SeriesMetadata");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Count",
|
||||
table: "Chapter");
|
||||
}
|
||||
}
|
||||
}
|
1351
API/Data/Migrations/20220108202027_PublicationStatus.Designer.cs
generated
Normal file
1351
API/Data/Migrations/20220108202027_PublicationStatus.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
37
API/Data/Migrations/20220108202027_PublicationStatus.cs
Normal file
37
API/Data/Migrations/20220108202027_PublicationStatus.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace API.Data.Migrations
|
||||
{
|
||||
public partial class PublicationStatus : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "PublicationStatus",
|
||||
table: "SeriesMetadata",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "TotalCount",
|
||||
table: "Chapter",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PublicationStatus",
|
||||
table: "SeriesMetadata");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TotalCount",
|
||||
table: "Chapter");
|
||||
}
|
||||
}
|
||||
}
|
@ -299,6 +299,9 @@ namespace API.Data.Migrations
|
||||
b.Property<int>("AgeRating")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CoverImage")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
@ -338,6 +341,9 @@ namespace API.Data.Migrations
|
||||
b.Property<string>("TitleName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("TotalCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("VolumeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
@ -494,9 +500,15 @@ namespace API.Data.Migrations
|
||||
b.Property<int>("AgeRating")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Language")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("PublicationStatus")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ReleaseYear")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
@ -72,6 +72,7 @@ public interface ISeriesRepository
|
||||
Task<IList<SeriesMetadata>> GetSeriesMetadataForIdsAsync(IEnumerable<int> seriesIds);
|
||||
Task<IList<AgeRatingDto>> GetAllAgeRatingsDtosForLibrariesAsync(List<int> libraryIds);
|
||||
Task<IList<LanguageDto>> GetAllLanguagesForLibrariesAsync(List<int> libraryIds);
|
||||
Task<IList<PublicationStatusDto>> GetAllPublicationStatusesDtosForLibrariesAsync(List<int> libraryIds);
|
||||
}
|
||||
|
||||
public class SeriesRepository : ISeriesRepository
|
||||
@ -425,7 +426,7 @@ public class SeriesRepository : ISeriesRepository
|
||||
private IList<MangaFormat> ExtractFilters(int libraryId, int userId, FilterDto filter, ref List<int> userLibraries,
|
||||
out List<int> allPeopleIds, out bool hasPeopleFilter, out bool hasGenresFilter, out bool hasCollectionTagFilter,
|
||||
out bool hasRatingFilter, out bool hasProgressFilter, out IList<int> seriesIds, out bool hasAgeRating, out bool hasTagsFilter,
|
||||
out bool hasLanguageFilter)
|
||||
out bool hasLanguageFilter, out bool hasPublicationFilter)
|
||||
{
|
||||
var formats = filter.GetSqlFilter();
|
||||
|
||||
@ -454,6 +455,7 @@ public class SeriesRepository : ISeriesRepository
|
||||
hasAgeRating = filter.AgeRating.Count > 0;
|
||||
hasTagsFilter = filter.Tags.Count > 0;
|
||||
hasLanguageFilter = filter.Languages.Count > 0;
|
||||
hasPublicationFilter = filter.PublicationStatus.Count > 0;
|
||||
|
||||
|
||||
bool ProgressComparison(int pagesRead, int totalPages)
|
||||
@ -541,7 +543,7 @@ public class SeriesRepository : ISeriesRepository
|
||||
var formats = ExtractFilters(libraryId, userId, filter, ref userLibraries,
|
||||
out var allPeopleIds, out var hasPeopleFilter, out var hasGenresFilter,
|
||||
out var hasCollectionTagFilter, out var hasRatingFilter, out var hasProgressFilter,
|
||||
out var seriesIds, out var hasAgeRating, out var hasTagsFilter, out var hasLanguageFilter);
|
||||
out var seriesIds, out var hasAgeRating, out var hasTagsFilter, out var hasLanguageFilter, out var hasPublicationFilter);
|
||||
|
||||
var query = _context.Series
|
||||
.Where(s => userLibraries.Contains(s.LibraryId)
|
||||
@ -555,6 +557,7 @@ public class SeriesRepository : ISeriesRepository
|
||||
&& (!hasAgeRating || filter.AgeRating.Contains(s.Metadata.AgeRating))
|
||||
&& (!hasTagsFilter || s.Metadata.Tags.Any(t => filter.Tags.Contains(t.Id)))
|
||||
&& (!hasLanguageFilter || filter.Languages.Contains(s.Metadata.Language))
|
||||
&& (!hasPublicationFilter || filter.PublicationStatus.Contains(s.Metadata.PublicationStatus))
|
||||
)
|
||||
.AsNoTracking();
|
||||
|
||||
@ -769,4 +772,18 @@ public class SeriesRepository : ISeriesRepository
|
||||
IsoCode = s
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public async Task<IList<PublicationStatusDto>> GetAllPublicationStatusesDtosForLibrariesAsync(List<int> libraryIds)
|
||||
{
|
||||
return await _context.Series
|
||||
.Where(s => libraryIds.Contains(s.LibraryId))
|
||||
.Select(s => s.Metadata.PublicationStatus)
|
||||
.Distinct()
|
||||
.Select(s => new PublicationStatusDto()
|
||||
{
|
||||
Value = s,
|
||||
Title = s.ToDescription()
|
||||
})
|
||||
.ToListAsync();
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,14 @@ namespace API.Entities
|
||||
/// Language for the Chapter/Issue
|
||||
/// </summary>
|
||||
public string Language { get; set; }
|
||||
/// <summary>
|
||||
/// Total number of issues in the series
|
||||
/// </summary>
|
||||
public int TotalCount { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// Number in the Total Count
|
||||
/// </summary>
|
||||
public int Count { get; set; } = 0;
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
23
API/Entities/Enums/PublicationStatus.cs
Normal file
23
API/Entities/Enums/PublicationStatus.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace API.Entities.Enums;
|
||||
|
||||
public enum PublicationStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Default Status. Publication is currently in progress
|
||||
/// </summary>
|
||||
[Description("On Going")]
|
||||
OnGoing = 0,
|
||||
/// <summary>
|
||||
/// Series is on temp or indefinite Hiatus
|
||||
/// </summary>
|
||||
[Description("Hiatus")]
|
||||
Hiatus = 1,
|
||||
/// <summary>
|
||||
/// Publication has finished releasing
|
||||
/// </summary>
|
||||
[Description("Completed")]
|
||||
Completed = 2
|
||||
|
||||
}
|
@ -14,7 +14,6 @@ namespace API.Entities.Metadata
|
||||
|
||||
public string Summary { get; set; }
|
||||
|
||||
|
||||
public ICollection<CollectionTag> CollectionTags { get; set; }
|
||||
|
||||
public ICollection<Genre> Genres { get; set; } = new List<Genre>();
|
||||
@ -36,6 +35,11 @@ namespace API.Entities.Metadata
|
||||
/// Language of the content (ISO 639-1 code)
|
||||
/// </summary>
|
||||
public string Language { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// Total number of issues in the series
|
||||
/// </summary>
|
||||
public int Count { get; set; } = 0;
|
||||
public PublicationStatus PublicationStatus { get; set; }
|
||||
|
||||
// Relationship
|
||||
public Series Series { get; set; }
|
||||
|
@ -107,6 +107,19 @@ public class MetadataService : IMetadataService
|
||||
chapter.Language = comicInfo.LanguageISO;
|
||||
}
|
||||
|
||||
if (comicInfo.Count > 0)
|
||||
{
|
||||
chapter.TotalCount = comicInfo.Count;
|
||||
}
|
||||
|
||||
if (int.Parse(comicInfo.Number) > 0)
|
||||
{
|
||||
chapter.Count = int.Parse(comicInfo.Number);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (comicInfo.Year > 0)
|
||||
{
|
||||
var day = Math.Max(comicInfo.Day, 1);
|
||||
@ -295,6 +308,13 @@ public class MetadataService : IMetadataService
|
||||
series.Metadata.AgeRating = chapters.Max(chapter => chapter.AgeRating);
|
||||
|
||||
|
||||
series.Metadata.Count = chapters.Max(chapter => chapter.TotalCount);
|
||||
series.Metadata.PublicationStatus = PublicationStatus.OnGoing;
|
||||
if (chapters.Max(chapter => chapter.Count) >= series.Metadata.Count)
|
||||
{
|
||||
series.Metadata.PublicationStatus = PublicationStatus.Completed;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(firstChapter.Summary))
|
||||
{
|
||||
series.Metadata.Summary = firstChapter.Summary;
|
||||
|
@ -0,0 +1,6 @@
|
||||
import { PublicationStatus } from "./publication-status";
|
||||
|
||||
export interface PublicationStatusDto {
|
||||
value: PublicationStatus;
|
||||
title: string;
|
||||
}
|
5
UI/Web/src/app/_models/metadata/publication-status.ts
Normal file
5
UI/Web/src/app/_models/metadata/publication-status.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export enum PublicationStatus {
|
||||
OnGoing = 0,
|
||||
Hiatus = 1,
|
||||
Completed = 2
|
||||
}
|
@ -27,6 +27,7 @@ export interface SeriesFilter {
|
||||
sortOptions: SortOptions | null;
|
||||
tags: Array<number>;
|
||||
languages: Array<string>;
|
||||
publicationStatus: Array<number>;
|
||||
}
|
||||
|
||||
export interface SortOptions {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { CollectionTag } from "./collection-tag";
|
||||
import { Genre } from "./genre";
|
||||
import { AgeRating } from "./metadata/age-rating";
|
||||
import { PublicationStatus } from "./metadata/publication-status";
|
||||
import { Person } from "./person";
|
||||
import { Tag } from "./tag";
|
||||
|
||||
@ -24,4 +25,5 @@ export interface SeriesMetadata {
|
||||
releaseYear: number;
|
||||
language: string;
|
||||
seriesId: number;
|
||||
publicationStatus: PublicationStatus;
|
||||
}
|
@ -8,6 +8,7 @@ import { Genre } from '../_models/genre';
|
||||
import { AgeRating } from '../_models/metadata/age-rating';
|
||||
import { AgeRatingDto } from '../_models/metadata/age-rating-dto';
|
||||
import { Language } from '../_models/metadata/language';
|
||||
import { PublicationStatusDto } from '../_models/metadata/publication-status-dto';
|
||||
import { Person } from '../_models/person';
|
||||
import { Tag } from '../_models/tag';
|
||||
|
||||
@ -44,6 +45,14 @@ export class MetadataService {
|
||||
return this.httpClient.get<Array<AgeRatingDto>>(this.baseUrl + method);;
|
||||
}
|
||||
|
||||
getAllPublicationStatus(libraries?: Array<number>) {
|
||||
let method = 'metadata/publication-status'
|
||||
if (libraries != undefined && libraries.length > 0) {
|
||||
method += '?libraryIds=' + libraries.join(',');
|
||||
}
|
||||
return this.httpClient.get<Array<PublicationStatusDto>>(this.baseUrl + method);;
|
||||
}
|
||||
|
||||
getAllTags(libraries?: Array<number>) {
|
||||
let method = 'metadata/tags'
|
||||
if (libraries != undefined && libraries.length > 0) {
|
||||
|
@ -212,7 +212,8 @@ export class SeriesService {
|
||||
sortOptions: null,
|
||||
ageRating: [],
|
||||
tags: [],
|
||||
languages: []
|
||||
languages: [],
|
||||
publicationStatus: [],
|
||||
};
|
||||
|
||||
if (filter === undefined) return data;
|
||||
|
@ -35,6 +35,7 @@ import { NavEventsToggleComponent } from './nav-events-toggle/nav-events-toggle.
|
||||
import { PersonRolePipe } from './person-role.pipe';
|
||||
import { SeriesMetadataDetailComponent } from './series-metadata-detail/series-metadata-detail.component';
|
||||
import { AllSeriesComponent } from './all-series/all-series.component';
|
||||
import { PublicationStatusPipe } from './publication-status.pipe';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@ -52,6 +53,7 @@ import { AllSeriesComponent } from './all-series/all-series.component';
|
||||
DashboardComponent,
|
||||
NavEventsToggleComponent,
|
||||
PersonRolePipe,
|
||||
PublicationStatusPipe,
|
||||
SeriesMetadataDetailComponent,
|
||||
AllSeriesComponent,
|
||||
],
|
||||
|
@ -309,6 +309,19 @@
|
||||
</app-typeahead>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2 mr-3" *ngIf="!filterSettings.publicationStatusDisabled">
|
||||
<label for="publication-status">Publication Status</label>
|
||||
<app-typeahead (selectedData)="updatePublicationStatus($event)" [settings]="publicationStatusSettings" [reset]="resetTypeaheads">
|
||||
<ng-template #badgeItem let-item let-position="idx">
|
||||
{{item.title}}
|
||||
</ng-template>
|
||||
<ng-template #optionItem let-item let-position="idx">
|
||||
{{item.title}}
|
||||
</ng-template>
|
||||
</app-typeahead>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center no-gutters">
|
||||
<div class="col-md-2 mr-3" *ngIf="!filterSettings.sortDisabled">
|
||||
<form [formGroup]="sortGroup">
|
||||
<div class="form-group">
|
||||
@ -326,16 +339,13 @@
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="row justify-content-center no-gutters">
|
||||
<div class="col-md-3 mr-3">
|
||||
</div>
|
||||
<div class="col-md-2 mr-3"></div>
|
||||
<div class="col-md-2 mr-3"></div>
|
||||
<div class="col-md-2 mr-3 mt-4">
|
||||
<button class="btn btn-secondary btn-block" (click)="clear()">Clear</button>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-2 mr-3 mt-4">
|
||||
<button class="btn btn-primary btn-block" (click)="apply()">Apply</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -11,6 +11,7 @@ import { MangaFormat } from 'src/app/_models/manga-format';
|
||||
import { AgeRating } from 'src/app/_models/metadata/age-rating';
|
||||
import { AgeRatingDto } from 'src/app/_models/metadata/age-rating-dto';
|
||||
import { Language } from 'src/app/_models/metadata/language';
|
||||
import { PublicationStatusDto } from 'src/app/_models/metadata/publication-status-dto';
|
||||
import { Pagination } from 'src/app/_models/pagination';
|
||||
import { Person, PersonRole } from 'src/app/_models/person';
|
||||
import { FilterItem, mangaFormatFilters, SeriesFilter, SortField } from 'src/app/_models/series-filter';
|
||||
@ -39,6 +40,7 @@ export class FilterSettings {
|
||||
ageRatingDisabled = false;
|
||||
tagsDisabled = false;
|
||||
languageDisabled = false;
|
||||
publicationStatusDisabled = false;
|
||||
}
|
||||
|
||||
@Component({
|
||||
@ -70,6 +72,7 @@ export class CardDetailLayoutComponent implements OnInit, OnDestroy {
|
||||
genreSettings: TypeaheadSettings<FilterItem<Genre>> = new TypeaheadSettings();
|
||||
collectionSettings: TypeaheadSettings<FilterItem<CollectionTag>> = new TypeaheadSettings();
|
||||
ageRatingSettings: TypeaheadSettings<FilterItem<AgeRatingDto>> = new TypeaheadSettings();
|
||||
publicationStatusSettings: TypeaheadSettings<FilterItem<PublicationStatusDto>> = new TypeaheadSettings();
|
||||
tagsSettings: TypeaheadSettings<FilterItem<Tag>> = new TypeaheadSettings();
|
||||
languageSettings: TypeaheadSettings<FilterItem<Language>> = new TypeaheadSettings();
|
||||
peopleSettings: {[PersonRole: string]: TypeaheadSettings<FilterItem<Person>>} = {};
|
||||
@ -84,7 +87,7 @@ export class CardDetailLayoutComponent implements OnInit, OnDestroy {
|
||||
libraries: Array<FilterItem<Library>> = [];
|
||||
genres: Array<FilterItem<Genre>> = [];
|
||||
persons: Array<FilterItem<Person>> = [];
|
||||
//collectionTags: Array<FilterItem<CollectionTag>> = [];
|
||||
|
||||
|
||||
readProgressGroup!: FormGroup;
|
||||
sortGroup!: FormGroup;
|
||||
@ -171,6 +174,7 @@ export class CardDetailLayoutComponent implements OnInit, OnDestroy {
|
||||
this.setupCollectionTagTypeahead();
|
||||
this.setupPersonTypeahead();
|
||||
this.setupAgeRatingSettings();
|
||||
this.setupPublicationStatusSettings();
|
||||
this.setupTagSettings();
|
||||
this.setupLanguageSettings();
|
||||
}
|
||||
@ -261,6 +265,29 @@ export class CardDetailLayoutComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
setupPublicationStatusSettings() {
|
||||
this.publicationStatusSettings.minCharacters = 0;
|
||||
this.publicationStatusSettings.multiple = true;
|
||||
this.publicationStatusSettings.id = 'publication-status';
|
||||
this.publicationStatusSettings.unique = true;
|
||||
this.publicationStatusSettings.addIfNonExisting = false;
|
||||
this.publicationStatusSettings.fetchFn = (filter: string) => {
|
||||
return this.metadataService.getAllPublicationStatus(this.filter.libraries).pipe(map(statuses => {
|
||||
return statuses.map(status => {
|
||||
return {
|
||||
title: status.title,
|
||||
value: status,
|
||||
selected: false,
|
||||
}
|
||||
})
|
||||
}));
|
||||
};
|
||||
this.publicationStatusSettings.compareFn = (options: FilterItem<PublicationStatusDto>[], filter: string) => {
|
||||
const f = filter.toLowerCase();
|
||||
return options.filter(m => m.title.toLowerCase() === f && this.utilityService.filter(m.title, filter));
|
||||
}
|
||||
}
|
||||
|
||||
setupTagSettings() {
|
||||
this.tagsSettings.minCharacters = 0;
|
||||
this.tagsSettings.multiple = true;
|
||||
@ -475,9 +502,6 @@ export class CardDetailLayoutComponent implements OnInit, OnDestroy {
|
||||
case PersonRole.Colorist:
|
||||
this.filter.colorist = persons.map(p => p.value.id);
|
||||
break;
|
||||
// case PersonRole.Artist:
|
||||
// this.filter.artist = persons.map(p => p.value.id);
|
||||
// break;
|
||||
case PersonRole.Editor:
|
||||
this.filter.editor = persons.map(p => p.value.id);
|
||||
break;
|
||||
@ -514,12 +538,15 @@ export class CardDetailLayoutComponent implements OnInit, OnDestroy {
|
||||
this.filter.ageRating = ratingDtos.map(item => item.value.value) || [];
|
||||
}
|
||||
|
||||
updatePublicationStatus(dtos: FilterItem<PublicationStatusDto>[]) {
|
||||
this.filter.publicationStatus = dtos.map(item => item.value.value) || [];
|
||||
}
|
||||
|
||||
updateLanguageRating(languages: FilterItem<Language>[]) {
|
||||
this.filter.languages = languages.map(item => item.value.isoCode) || [];
|
||||
}
|
||||
|
||||
updateReadStatus(status: string) {
|
||||
console.log('readstatus: ', this.filter.readStatus);
|
||||
if (status === 'read') {
|
||||
this.filter.readStatus.read = !this.filter.readStatus.read;
|
||||
} else if (status === 'inProgress') {
|
||||
|
19
UI/Web/src/app/publication-status.pipe.ts
Normal file
19
UI/Web/src/app/publication-status.pipe.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { PublicationStatus } from './_models/metadata/publication-status';
|
||||
|
||||
@Pipe({
|
||||
name: 'publicationStatus'
|
||||
})
|
||||
export class PublicationStatusPipe implements PipeTransform {
|
||||
|
||||
transform(value: PublicationStatus): string {
|
||||
switch (value) {
|
||||
case PublicationStatus.OnGoing: return 'Ongoing';
|
||||
case PublicationStatus.Hiatus: return 'Hiatus';
|
||||
case PublicationStatus.Completed: return 'Completed';
|
||||
|
||||
default: return '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
<!-- tooltip here explaining how this is year of first issue -->
|
||||
<app-tag-badge *ngIf="seriesMetadata.releaseYear > 0" title="Release date">{{seriesMetadata.releaseYear}}</app-tag-badge>
|
||||
<app-tag-badge *ngIf="seriesMetadata.language !== null && seriesMetadata.language !== ''" title="Language">{{seriesMetadata.language}}</app-tag-badge>
|
||||
<app-tag-badge title="Publication Status">{{seriesMetadata.publicationStatus | publicationStatus}}</app-tag-badge>
|
||||
<app-tag-badge [selectionMode]="TagBadgeCursor.NotAllowed">
|
||||
<app-series-format [format]="series.format">{{utilityService.mangaFormat(series.format)}}</app-series-format>
|
||||
</app-tag-badge>
|
||||
|
Loading…
x
Reference in New Issue
Block a user