Fixed up code comments for Amelia.

Fixed a bug where not all detail pages had the same size font.

Fixed series detail page not having subtitle as a themeable variable (--detail-subtitle-color).
This commit is contained in:
Joseph Milazzo 2025-05-07 19:01:03 -05:00
parent bbea28fd05
commit 9844503671
41 changed files with 200 additions and 106 deletions

View file

@ -32,11 +32,7 @@ public class PersonServiceTests: AbstractDbTest
Name= "Delores Casey",
NormalizedName = "Delores Casey".ToNormalized(),
Description = "Hi, I'm Delores Casey!",
Aliases = [new PersonAlias
{
Alias = "Casey, Delores",
NormalizedAlias = "Casey, Delores".ToNormalized(),
}],
Aliases = [new PersonAliasBuilder("Casey, Delores").Build()],
AniListId = 27,
};

View file

@ -8,6 +8,7 @@ using API.Data;
using API.Data.Repositories;
using API.DTOs;
using API.DTOs.Metadata;
using API.DTOs.Person;
using API.DTOs.SeriesDetail;
using API.Entities;
using API.Entities.Enums;

View file

@ -6,9 +6,9 @@ using System.Threading.Tasks;
using API.Constants;
using API.Data;
using API.Data.Repositories;
using API.DTOs;
using API.DTOs.Filtering;
using API.DTOs.Metadata;
using API.DTOs.Person;
using API.DTOs.Recommendation;
using API.DTOs.SeriesDetail;
using API.Entities.Enums;

View file

@ -15,6 +15,7 @@ using API.DTOs.CollectionTags;
using API.DTOs.Filtering;
using API.DTOs.Filtering.v2;
using API.DTOs.OPDS;
using API.DTOs.Person;
using API.DTOs.Progress;
using API.DTOs.Search;
using API.Entities;

View file

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using API.Data;
using API.Data.Repositories;
using API.DTOs;
using API.DTOs.Person;
using API.Entities.Enums;
using API.Extensions;
using API.Helpers;

View file

@ -4,7 +4,7 @@ using System.Threading.Tasks;
using API.Constants;
using API.Data;
using API.Data.Repositories;
using API.DTOs;
using API.DTOs.Person;
using API.DTOs.ReadingLists;
using API.Entities.Enums;
using API.Extensions;

View file

@ -63,6 +63,7 @@ public class SearchController : BaseApiController
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());
if (user == null) return Unauthorized();
var libraries = _unitOfWork.LibraryRepository.GetLibraryIdsForUserIdAsync(user.Id, QueryContext.Search).ToList();
if (libraries.Count == 0) return BadRequest(await _localizationService.Translate(User.GetUserId(), "libraries-restricted"));

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using API.DTOs.Metadata;
using API.DTOs.Person;
using API.Entities.Enums;
using API.Entities.Interfaces;

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using API.DTOs.Person;
using API.Entities.Enums;
namespace API.DTOs.Metadata;

View file

@ -1,4 +1,6 @@
namespace API.DTOs;
using API.DTOs.Person;
namespace API.DTOs;
/// <summary>
/// Used to browse writers and click in to see their series

View file

@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace API.DTOs;
namespace API.DTOs.Person;
#nullable enable
public class PersonDto
@ -13,6 +13,7 @@ public class PersonDto
public string? SecondaryColor { get; set; }
public string? CoverImage { get; set; }
public List<string> Aliases { get; set; } = [];
public string? Description { get; set; }
/// <summary>

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using API.DTOs.Person;
namespace API.DTOs.ReadingLists;

View file

@ -2,6 +2,7 @@
using API.DTOs.Collection;
using API.DTOs.CollectionTags;
using API.DTOs.Metadata;
using API.DTOs.Person;
using API.DTOs.Reader;
using API.DTOs.ReadingLists;

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using API.DTOs.Metadata;
using API.DTOs.Person;
using API.Entities.Enums;
namespace API.DTOs;

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using API.DTOs.Metadata;
using API.DTOs.Person;
using API.Entities.Enums;
namespace API.DTOs;

View file

@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace API.Data.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20250504212806_PersonAliases")]
[Migration("20250507221026_PersonAliases")]
partial class PersonAliases
{
/// <inheritdoc />
@ -1851,7 +1851,7 @@ namespace API.Data.Migrations
b.Property<string>("NormalizedAlias")
.HasColumnType("TEXT");
b.Property<int?>("PersonId")
b.Property<int>("PersonId")
.HasColumnType("INTEGER");
b.HasKey("Id");
@ -3109,9 +3109,13 @@ namespace API.Data.Migrations
modelBuilder.Entity("API.Entities.Person.PersonAlias", b =>
{
b.HasOne("API.Entities.Person.Person", null)
b.HasOne("API.Entities.Person.Person", "Person")
.WithMany("Aliases")
.HasForeignKey("PersonId");
.HasForeignKey("PersonId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Person");
});
modelBuilder.Entity("API.Entities.Person.SeriesMetadataPeople", b =>

View file

@ -18,7 +18,7 @@ namespace API.Data.Migrations
.Annotation("Sqlite:Autoincrement", true),
Alias = table.Column<string>(type: "TEXT", nullable: true),
NormalizedAlias = table.Column<string>(type: "TEXT", nullable: true),
PersonId = table.Column<int>(type: "INTEGER", nullable: true)
PersonId = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
@ -27,7 +27,8 @@ namespace API.Data.Migrations
name: "FK_PersonAlias_Person_PersonId",
column: x => x.PersonId,
principalTable: "Person",
principalColumn: "Id");
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(

View file

@ -1848,7 +1848,7 @@ namespace API.Data.Migrations
b.Property<string>("NormalizedAlias")
.HasColumnType("TEXT");
b.Property<int?>("PersonId")
b.Property<int>("PersonId")
.HasColumnType("INTEGER");
b.HasKey("Id");
@ -3106,9 +3106,13 @@ namespace API.Data.Migrations
modelBuilder.Entity("API.Entities.Person.PersonAlias", b =>
{
b.HasOne("API.Entities.Person.Person", null)
b.HasOne("API.Entities.Person.Person", "Person")
.WithMany("Aliases")
.HasForeignKey("PersonId");
.HasForeignKey("PersonId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Person");
});
modelBuilder.Entity("API.Entities.Person.SeriesMetadataPeople", b =>

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using API.DTOs;
using API.DTOs.Person;
using API.Entities.Enums;
using API.Entities.Person;
using API.Extensions;

View file

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using API.Data.Misc;
using API.DTOs;
using API.DTOs.Person;
using API.DTOs.ReadingLists;
using API.Entities;
using API.Entities.Enums;

View file

@ -15,6 +15,7 @@ using API.DTOs.Filtering;
using API.DTOs.Filtering.v2;
using API.DTOs.KavitaPlus.Metadata;
using API.DTOs.Metadata;
using API.DTOs.Person;
using API.DTOs.ReadingLists;
using API.DTOs.Recommendation;
using API.DTOs.Scrobbling;
@ -455,11 +456,18 @@ public class SeriesRepository : ISeriesRepository
.ProjectTo<AppUserCollectionDto>(_mapper.ConfigurationProvider)
.ToListAsync();
result.Persons = await _context.SeriesMetadata
// I can't work out how to map people in DB layer
var personIds = await _context.SeriesMetadata
.SearchPeople(searchQuery, seriesIds)
.Take(maxRecords)
.OrderBy(t => t.NormalizedName)
.Select(p => p.Id)
.Distinct()
.OrderBy(id => id)
.Take(maxRecords)
.ToListAsync();
result.Persons = await _context.Person
.Where(p => personIds.Contains(p.Id))
.OrderBy(p => p.NormalizedName)
.ProjectTo<PersonDto>(_mapper.ConfigurationProvider)
.ToListAsync();
@ -475,8 +483,8 @@ public class SeriesRepository : ISeriesRepository
.ProjectTo<TagDto>(_mapper.ConfigurationProvider)
.ToListAsync();
result.Files = new List<MangaFileDto>();
result.Chapters = new List<ChapterDto>();
result.Files = [];
result.Chapters = (List<ChapterDto>) [];
if (includeChapterAndFiles)

View file

@ -46,8 +46,8 @@ public class Person : IHasCoverImage
//public long MetronId { get; set; } = 0;
// Relationships
public ICollection<ChapterPeople> ChapterPeople { get; set; } = new List<ChapterPeople>();
public ICollection<SeriesMetadataPeople> SeriesMetadataPeople { get; set; } = new List<SeriesMetadataPeople>();
public ICollection<ChapterPeople> ChapterPeople { get; set; } = [];
public ICollection<SeriesMetadataPeople> SeriesMetadataPeople { get; set; } = [];
public void ResetColorScape()

View file

@ -3,8 +3,9 @@ namespace API.Entities.Person;
public class PersonAlias
{
public int Id { get; set; }
public required string Alias { get; set; }
public required string NormalizedAlias { get; set; }
public string Alias { get; set; }
public string NormalizedAlias { get; set; }
public int PersonId { get; set; }
public Person Person { get; set; }
}

View file

@ -50,27 +50,26 @@ public static class SearchQueryableExtensions
// Get people from SeriesMetadata
var peopleFromSeriesMetadata = queryable
.Where(sm => seriesIds.Contains(sm.SeriesId))
.SelectMany(sm => sm.People)
.Include(sp => sp.Person.Aliases)
.Where(p => (p.Person.Name != null && EF.Functions.Like(p.Person.Name, $"%{searchQuery}%"))
|| p.Person.Aliases.Any(pa => EF.Functions.Like(pa.Alias, $"%{searchQuery}%")))
.Select(p => p.Person);
.SelectMany(sm => sm.People.Select(sp => sp.Person))
.Where(p =>
EF.Functions.Like(p.Name, $"%{searchQuery}%") ||
p.Aliases.Any(pa => EF.Functions.Like(pa.Alias, $"%{searchQuery}%"))
);
// Get people from ChapterPeople by navigating through Volume -> Series
var peopleFromChapterPeople = queryable
.Where(sm => seriesIds.Contains(sm.SeriesId))
.SelectMany(sm => sm.Series.Volumes)
.SelectMany(v => v.Chapters)
.SelectMany(ch => ch.People)
.Include(cp => cp.Person.Aliases)
.Where(p => (p.Person.Name != null && EF.Functions.Like(p.Person.Name, $"%{searchQuery}%"))
|| p.Person.Aliases.Any(pa => EF.Functions.Like(pa.Alias, $"%{searchQuery}%")))
.Select(cp => cp.Person);
.SelectMany(ch => ch.People.Select(cp => cp.Person))
.Where(p =>
EF.Functions.Like(p.Name, $"%{searchQuery}%") ||
p.Aliases.Any(pa => EF.Functions.Like(pa.Alias, $"%{searchQuery}%"))
);
// Combine both queries and ensure distinct results
return peopleFromSeriesMetadata
.Union(peopleFromChapterPeople)
.Distinct()
.Select(p => p)
.OrderBy(p => p.NormalizedName);
}

View file

@ -15,6 +15,7 @@ using API.DTOs.KavitaPlus.Manage;
using API.DTOs.KavitaPlus.Metadata;
using API.DTOs.MediaErrors;
using API.DTOs.Metadata;
using API.DTOs.Person;
using API.DTOs.Progress;
using API.DTOs.Reader;
using API.DTOs.ReadingLists;
@ -68,7 +69,8 @@ public class AutoMapperProfiles : Profile
CreateMap<AppUserCollection, AppUserCollectionDto>()
.ForMember(dest => dest.Owner, opt => opt.MapFrom(src => src.AppUser.UserName))
.ForMember(dest => dest.ItemCount, opt => opt.MapFrom(src => src.Items.Count));
CreateMap<Person, PersonDto>();
CreateMap<Person, PersonDto>()
.ForMember(dest => dest.Aliases, opt => opt.MapFrom(src => src.Aliases.Select(s => s.Alias)));
CreateMap<Genre, GenreTagDto>();
CreateMap<Tag, TagDto>();
CreateMap<AgeRating, AgeRatingDto>();

View file

@ -0,0 +1,19 @@
using API.Entities.Person;
using API.Extensions;
namespace API.Helpers.Builders;
public class PersonAliasBuilder : IEntityBuilder<PersonAlias>
{
private readonly PersonAlias _alias;
public PersonAlias Build() => _alias;
public PersonAliasBuilder(string name)
{
_alias = new PersonAlias()
{
Alias = name.Trim(),
NormalizedAlias = name.ToNormalized(),
};
}
}

View file

@ -39,11 +39,8 @@ public class PersonBuilder : IEntityBuilder<Person>
return this;
}
_person.Aliases.Add(new PersonAlias()
{
Alias = alias,
NormalizedAlias = alias.ToNormalized(),
});
_person.Aliases.Add(new PersonAliasBuilder(alias).Build());
return this;
}

View file

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using API.Data;
using API.Entities.Person;
using API.Extensions;
using API.Helpers.Builders;
namespace API.Services;
@ -68,11 +69,7 @@ public class PersonService(IUnitOfWork unitOfWork): IPersonService
MergeChapterPeople(dst, src);
MergeSeriesMetadataPeople(dst, src);
dst.Aliases.Add(new PersonAlias
{
Alias = src.Name,
NormalizedAlias = src.NormalizedName,
});
dst.Aliases.Add(new PersonAliasBuilder(src.Name).Build());
foreach (var alias in src.Aliases)
{
@ -84,12 +81,14 @@ public class PersonService(IUnitOfWork unitOfWork): IPersonService
await unitOfWork.CommitAsync();
}
private void MergeChapterPeople(Person dst, Person src)
private static void MergeChapterPeople(Person dst, Person src)
{
foreach (var chapter in src.ChapterPeople)
{
var alreadyPresent = dst.ChapterPeople
.Any(x => x.ChapterId == chapter.ChapterId && x.Role == chapter.Role);
if (alreadyPresent) continue;
dst.ChapterPeople.Add(new ChapterPeople
@ -103,12 +102,13 @@ public class PersonService(IUnitOfWork unitOfWork): IPersonService
}
}
private void MergeSeriesMetadataPeople(Person dst, Person src)
private static void MergeSeriesMetadataPeople(Person dst, Person src)
{
foreach (var series in src.SeriesMetadataPeople)
{
var alreadyPresent = dst.SeriesMetadataPeople
.Any(x => x.SeriesMetadataId == series.SeriesMetadataId && x.Role == series.Role);
if (alreadyPresent) continue;
dst.SeriesMetadataPeople.Add(new SeriesMetadataPeople
@ -125,9 +125,8 @@ public class PersonService(IUnitOfWork unitOfWork): IPersonService
public async Task<bool> UpdatePersonAliasesAsync(Person person, IList<string> aliases)
{
var normalizedAliases = aliases
.Select(a => a.ToNormalized().Trim())
.Where(a => !string.IsNullOrWhiteSpace(a))
.Where(a => a != person.NormalizedName)
.Select(a => a.ToNormalized())
.Where(a => !string.IsNullOrEmpty(a) && a != person.NormalizedName)
.ToList();
if (normalizedAliases.Count == 0)
@ -141,11 +140,7 @@ public class PersonService(IUnitOfWork unitOfWork): IPersonService
if (others.Count != 0) return false;
person.Aliases = aliases.Select(a => new PersonAlias
{
Alias = a.Trim(),
NormalizedAlias = a.Trim().ToNormalized()
}).ToList();
person.Aliases = aliases.Select(a => new PersonAliasBuilder(a).Build()).ToList();
return true;
}

View file

@ -10,6 +10,7 @@ using API.DTOs.Collection;
using API.DTOs.KavitaPlus.ExternalMetadata;
using API.DTOs.KavitaPlus.Metadata;
using API.DTOs.Metadata.Matching;
using API.DTOs.Person;
using API.DTOs.Recommendation;
using API.DTOs.Scrobbling;
using API.DTOs.SeriesDetail;
@ -20,6 +21,7 @@ using API.Entities.MetadataMatching;
using API.Entities.Person;
using API.Extensions;
using API.Helpers;
using API.Helpers.Builders;
using API.Services.Tasks.Metadata;
using API.Services.Tasks.Scanner.Parser;
using API.SignalR;
@ -657,11 +659,7 @@ public class ExternalMetadataService : IExternalMetadataService
if (existingPeopleDictionary.TryGetValue(mapping.AlternativeName.ToNormalized(), out var person))
{
modified = true;
person.Aliases.Add(new PersonAlias
{
Alias = mapping.PreferredName,
NormalizedAlias = mapping.PreferredName.ToNormalized(),
});
person.Aliases.Add(new PersonAliasBuilder(mapping.PreferredName).Build());
}
}

View file

@ -7,6 +7,7 @@ using API.Comparators;
using API.Data;
using API.Data.Repositories;
using API.DTOs;
using API.DTOs.Person;
using API.DTOs.SeriesDetail;
using API.Entities;
using API.Entities.Enums;

View file

@ -13,7 +13,7 @@
}
.subtitle {
color: lightgrey;
color: var(--detail-subtitle-color);
font-weight: bold;
font-size: 0.8rem;
}

View file

@ -22,6 +22,7 @@ export interface Person extends IHasCover {
id: number;
name: string;
description: string;
aliases: Array<string>;
coverImage?: string;
coverImageLocked: boolean;
malId?: number;

View file

@ -119,6 +119,18 @@
</div>
<div class="ms-1">
<div>{{item.name}}</div>
@if (item.aliases.length > 0) {
<span class="small-text">
{{t('person-aka-label')}}
@for(alias of item.aliases; track alias; let last = $last) {
<span>{{alias}}</span>
@if (!last) {
<span>, </span>
}
}
</span>
}
</div>
</div>
</ng-template>

View file

@ -138,3 +138,7 @@
}
}
}
.small-text {
font-size: 0.8rem;
}

View file

@ -16,13 +16,6 @@
}
</h2>
</ng-container>
<ng-container subtitle>
@if (aliases$ | async; as aliases) {
@if (aliases.length > 0) {
<span>{{t('aka')}} {{aliases.join(", ")}}</span>
}
}
</ng-container>
</app-side-nav-companion-bar>
</div>
@ -50,15 +43,43 @@
<div class="col-xl-10 col-lg-7 col-md-12 col-xs-12 col-sm-12 mt-2">
<div class="row g-0 mt-2">
<app-read-more [text]="person.description || t('no-info')"></app-read-more>
<app-read-more [maxLength]="500" [text]="person.description || t('no-info')"></app-read-more>
@if (person.aliases.length > 0) {
<span class="fw-bold mt-2">{{t('aka-title')}}</span>
<div>
<app-badge-expander [items]="person.aliases"
[itemsTillExpander]="6">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon">{{item}}</a>
</ng-template>
</app-badge-expander>
</div>
}
@if (roles$ | async; as roles) {
<div class="mt-1">
<h5>{{t('all-roles')}}</h5>
@for(role of roles; track role) {
<app-tag-badge [selectionMode]="TagBadgeCursor.Clickable" (click)="loadFilterByRole(role)">{{role | personRole}}</app-tag-badge>
}
</div>
@if (roles.length > 0) {
<span class="fw-bold mt-2">{{t('all-roles')}}</span>
<div>
<app-badge-expander [items]="roles"
[itemsTillExpander]="6">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon" (click)="loadFilterByRole(item)">{{item | personRole}}</a>
</ng-template>
</app-badge-expander>
</div>
}
<!-- -->
<!-- <div class="mt-1">-->
<!-- <h5>{{t('all-roles')}}</h5>-->
<!-- @for(role of roles; track role) {-->
<!-- <app-tag-badge [selectionMode]="TagBadgeCursor.Clickable" (click)="loadFilterByRole(role)">{{role | personRole}}</app-tag-badge>-->
<!-- }-->
<!-- </div>-->
}
</div>

View file

@ -25,7 +25,7 @@ import {CarouselReelComponent} from "../carousel/_components/carousel-reel/carou
import {FilterComparison} from "../_models/metadata/v2/filter-comparison";
import {FilterUtilitiesService} from "../shared/_services/filter-utilities.service";
import {SeriesFilterV2} from "../_models/metadata/v2/series-filter-v2";
import {allPeople, personRoleForFilterField} from "../_models/metadata/v2/filter-field";
import {allPeople, FilterField, personRoleForFilterField} from "../_models/metadata/v2/filter-field";
import {Series} from "../_models/series";
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import {FilterCombination} from "../_models/metadata/v2/filter-combination";
@ -44,6 +44,7 @@ import {LicenseService} from "../_services/license.service";
import {SafeUrlPipe} from "../_pipes/safe-url.pipe";
import {MergePersonModalComponent} from "./_modal/merge-person-modal/merge-person-modal.component";
import {EVENTS, MessageHubService} from "../_services/message-hub.service";
import {BadgeExpanderComponent} from "../shared/badge-expander/badge-expander.component";
interface PersonMergeEvent {
srcId: number,
@ -53,24 +54,25 @@ interface PersonMergeEvent {
@Component({
selector: 'app-person-detail',
imports: [
AsyncPipe,
ImageComponent,
SideNavCompanionBarComponent,
ReadMoreComponent,
TagBadgeComponent,
PersonRolePipe,
CarouselReelComponent,
CardItemComponent,
CardActionablesComponent,
TranslocoDirective,
ChapterCardComponent,
SafeUrlPipe
],
templateUrl: './person-detail.component.html',
styleUrl: './person-detail.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
selector: 'app-person-detail',
imports: [
AsyncPipe,
ImageComponent,
SideNavCompanionBarComponent,
ReadMoreComponent,
TagBadgeComponent,
PersonRolePipe,
CarouselReelComponent,
CardItemComponent,
CardActionablesComponent,
TranslocoDirective,
ChapterCardComponent,
SafeUrlPipe,
BadgeExpanderComponent
],
templateUrl: './person-detail.component.html',
styleUrl: './person-detail.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PersonDetailComponent implements OnInit {
private readonly route = inject(ActivatedRoute);
@ -104,6 +106,7 @@ export class PersonDetailComponent implements OnInit {
personActions: Array<ActionItem<Person>> = this.actionService.getPersonActions(this.handleAction.bind(this));
chaptersByRole: any = {};
anilistUrl: string = '';
private readonly personSubject = new BehaviorSubject<Person | null>(null);
protected readonly person$ = this.personSubject.asObservable().pipe(tap(p => {
if (p?.aniListId) {
@ -291,4 +294,6 @@ export class PersonDetailComponent implements OnInit {
action.callback(action, this.person);
}
}
protected readonly FilterField = FilterField;
}

View file

@ -130,7 +130,7 @@
<span class="fw-bold">{{t('publication-status-title')}}</span>
<div>
@if (seriesMetadata.publicationStatus | publicationStatus; as pubStatus) {
<a class="dark-exempt btn-icon" (click)="openFilter(FilterField.PublicationStatus, seriesMetadata.publicationStatus)"
<a class="dark-exempt btn-icon font-size" (click)="openFilter(FilterField.PublicationStatus, seriesMetadata!.publicationStatus)"
href="javascript:void(0);"
[ngbTooltip]="t('publication-status-tooltip') + (seriesMetadata.totalCount === 0 ? '' : ' (' + seriesMetadata.maxCount + ' / ' + seriesMetadata.totalCount + ')')">
{{pubStatus}}

View file

@ -30,3 +30,7 @@
:host ::ng-deep .card-actions.btn-actions .btn {
padding: 0.375rem 0.75rem;
}
.font-size {
font-size: 0.8rem;
}

View file

@ -6,3 +6,7 @@
height: 35px;
overflow: hidden;
}
::ng-deep .badge-expander .content a {
font-size: 0.8rem;
}

View file

@ -1103,7 +1103,7 @@
},
"person-detail": {
"aka": "Also known as ",
"aka-title": "Also known as ",
"known-for-title": "Known For",
"individual-role-title": "As a {{role}}",
"browse-person-title": "All Works of {{name}}",
@ -1859,7 +1859,8 @@
"logout": "Logout",
"all-filters": "Smart Filters",
"nav-link-header": "Navigation Options",
"close": "{{common.close}}"
"close": "{{common.close}}",
"person-aka-label": "{{person-detail.aka-title}}:"
},
"promoted-icon": {

View file

@ -436,4 +436,7 @@
--login-input-font-family: 'League Spartan', sans-serif;
--login-input-placeholder-opacity: 0.5;
--login-input-placeholder-color: #fff;
/** Series Detail **/
--detail-subtitle-color: lightgrey;
}