Don't load all people for search, display series being merged in
This commit is contained in:
parent
940fe80609
commit
39b6382467
6 changed files with 44 additions and 8 deletions
|
|
@ -48,6 +48,13 @@ public class PersonController : BaseApiController
|
|||
return Ok(await _unitOfWork.PersonRepository.GetPersonDtoByName(name, User.GetUserId()));
|
||||
}
|
||||
|
||||
[HttpGet("search-people")]
|
||||
public async Task<ActionResult<List<PersonDto>>> SearchPeople([FromQuery] string name)
|
||||
{
|
||||
var people = await _unitOfWork.PersonRepository.SearchPeople(name);
|
||||
return Ok(people.Select(person => _mapper.Map<PersonDto>(person)).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all roles for a Person
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ public interface IPersonRepository
|
|||
/// <returns></returns>
|
||||
Task<IList<Person>> GetPeopleByNames(List<string> normalizedNames, PersonIncludes includes = PersonIncludes.Aliases);
|
||||
Task<Person?> GetPersonByAniListId(int aniListId, PersonIncludes includes = PersonIncludes.Aliases);
|
||||
|
||||
Task<IList<Person>> SearchPeople(string query, PersonIncludes includes = PersonIncludes.Aliases);
|
||||
}
|
||||
|
||||
public class PersonRepository : IPersonRepository
|
||||
|
|
@ -303,6 +305,15 @@ public class PersonRepository : IPersonRepository
|
|||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<Person>> SearchPeople(string query, PersonIncludes includes = PersonIncludes.Aliases)
|
||||
{
|
||||
return await _context.Person
|
||||
.Includes(includes)
|
||||
.Where(p => EF.Functions.Like(p.Name, $"%{query}%")
|
||||
|| p.Aliases.Any(pa => EF.Functions.Like(pa.Alias, $"%{query}%")))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<Person>> GetAllPeople(PersonIncludes includes = PersonIncludes.Aliases)
|
||||
{
|
||||
return await _context.Person
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ export class PersonService {
|
|||
return this.httpClient.get<Person | null>(this.baseUrl + `person?name=${name}`);
|
||||
}
|
||||
|
||||
getAliases(personId: number) {
|
||||
return this.httpClient.get<Array<string>>(this.baseUrl + `person/aliases?personId=${personId}`);
|
||||
searchPerson(name: string) {
|
||||
return this.httpClient.get<Array<Person>>(this.baseUrl + `person/search-people?name=${name}`);
|
||||
}
|
||||
|
||||
getRolesForPerson(personId: number) {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,15 @@
|
|||
</ng-template>
|
||||
</app-badge-expander>
|
||||
|
||||
@if (knownFor$ | async; as knownFor) {
|
||||
<h5 class="mt-2">{{t('known-for-title')}}</h5>
|
||||
|
||||
<app-badge-expander [items]="knownFor">
|
||||
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
|
||||
{{item.name}}
|
||||
</ng-template>
|
||||
</app-badge-expander>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import {Component, EventEmitter, inject, Input, OnInit} from '@angular/core';
|
||||
import {Component, DestroyRef, EventEmitter, inject, Input, OnInit} from '@angular/core';
|
||||
import {Person} from "../../../_models/metadata/person";
|
||||
import {PersonService} from "../../../_services/person.service";
|
||||
import {NgbActiveModal} from "@ng-bootstrap/ng-bootstrap";
|
||||
|
|
@ -8,10 +8,13 @@ import {TypeaheadComponent} from "../../../typeahead/_components/typeahead.compo
|
|||
import {TypeaheadSettings} from "../../../typeahead/_models/typeahead-settings";
|
||||
import {map} from "rxjs/operators";
|
||||
import {UtilityService} from "../../../shared/_services/utility.service";
|
||||
import {MetadataService} from "../../../_services/metadata.service";
|
||||
import {SettingItemComponent} from "../../../settings/_components/setting-item/setting-item.component";
|
||||
import {BadgeExpanderComponent} from "../../../shared/badge-expander/badge-expander.component";
|
||||
import {FilterField} from "../../../_models/metadata/v2/filter-field";
|
||||
import {Observable, of} from "rxjs";
|
||||
import {Series} from "../../../_models/series";
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
import {AsyncPipe} from "@angular/common";
|
||||
|
||||
@Component({
|
||||
selector: 'app-merge-person-modal',
|
||||
|
|
@ -19,7 +22,8 @@ import {FilterField} from "../../../_models/metadata/v2/filter-field";
|
|||
TranslocoDirective,
|
||||
TypeaheadComponent,
|
||||
SettingItemComponent,
|
||||
BadgeExpanderComponent
|
||||
BadgeExpanderComponent,
|
||||
AsyncPipe
|
||||
],
|
||||
templateUrl: './merge-person-modal.component.html',
|
||||
styleUrl: './merge-person-modal.component.scss'
|
||||
|
|
@ -28,7 +32,7 @@ export class MergePersonModalComponent implements OnInit {
|
|||
|
||||
private readonly personService = inject(PersonService);
|
||||
public readonly utilityService = inject(UtilityService);
|
||||
private readonly metadataService = inject(MetadataService);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly modal = inject(NgbActiveModal);
|
||||
protected readonly toastr = inject(ToastrService);
|
||||
|
||||
|
|
@ -38,6 +42,7 @@ export class MergePersonModalComponent implements OnInit {
|
|||
@Input({required: true}) person!: Person;
|
||||
|
||||
mergee: Person | null = null;
|
||||
knownFor$: Observable<Series[]> | null = null;
|
||||
|
||||
save() {
|
||||
if (!this.mergee) {
|
||||
|
|
@ -67,7 +72,8 @@ export class MergePersonModalComponent implements OnInit {
|
|||
return a.name == b.name;
|
||||
}
|
||||
this.typeAheadSettings.fetchFn = (filter: string) => {
|
||||
return this.metadataService.getAllPeople().pipe(map(people => {
|
||||
if (filter.length == 0) return of([]);
|
||||
return this.personService.searchPerson(filter).pipe(map(people => {
|
||||
return people.filter(p => this.utilityService.filter(p.name, filter) && p.id != this.person.id);
|
||||
}));
|
||||
};
|
||||
|
|
@ -80,6 +86,8 @@ export class MergePersonModalComponent implements OnInit {
|
|||
|
||||
this.typeAheadUnfocus.emit(this.typeAheadSettings.id);
|
||||
this.mergee = people[0];
|
||||
this.knownFor$ = this.personService.getSeriesMostKnownFor(this.mergee.id)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef));
|
||||
}
|
||||
|
||||
protected readonly FilterField = FilterField;
|
||||
|
|
|
|||
|
|
@ -2278,7 +2278,8 @@
|
|||
"save": "{{common.save}}",
|
||||
"src": "Merge Person",
|
||||
"merge-warning": "If you proceed, the selected person will be removed. If the target person has no existing names, the selected person's name will be added as their first name. Otherwise, the selected person's name will be added as an additional alias.",
|
||||
"alias-title": "New aliases"
|
||||
"alias-title": "New aliases",
|
||||
"known-for-title": "Known for"
|
||||
},
|
||||
|
||||
"day-breakdown": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue