- GetVisibleAsset: accept EAccessLevel enum instead of bool isCuratorOrAbove
- Admin: sees all assets including deleted
- Curator: sees own deleted + all non-deleted
- Maintainer/User: only non-deleted + visibility filtering
- BulkUpdate: Maintainer can update albums of persons they maintain
- Delete: Maintainer can delete albums of persons they maintain
- BulkDelete: same scoped filtering
Previously Maintainer saw all people like Curator+. Now:
- Curator+: sees all people
- Maintainer: sees Public + Protected + persons they maintain
- User: sees Public + Protected only
Replaces the static <select> with a server-side searchable combobox
in the album edit modal. Fixes issues where the person dropdown was
empty and the name field was not pre-filled on edit.
- Server-side person search (trigram-indexed ILIKE, 20 results)
- 2-character minimum before search triggers
- pre-populates input with current person name when editing
- position: fixed via JS to escape modal-body overflow clipping
Closes#123
- Remove stale Npgsql legacy timestamp switch note (removed from code)
- Fix EF Core version mismatch description (Tools 8.0.15, not CLI)
- Expand analyzer rules to cover MS001–MS004
Replace manual album state management (inline AlbumCard loop, own
infinite scroll, own sentinel/observer, _ = ReloadAlbums() discard
lambdas) with <AlbumGrid> using a new FetchAlbums delegate parameter.
- AlbumGrid.razor: add FetchAlbums Func parameter; use it in
Reload()/LoadMoreAlbums() when set
- CosplayerDetail.razor: replace manual album rendering + state with
<AlbumGrid FetchAlbums=@FetchPersonAlbums />; remove all album
state management fields (allAlbumsDict, currentAlbumPage, etc.),
ReloadAlbums/LoadMoreAlbums/OnAfterRenderAsync methods, and
IAsyncDisposable; SortFilterBar now uses clean lambdas
- CosplayerDetail.razor.css: remove unused album-grid overrides
Closes#120
Convert <div @onclick> -> NavigationManager.NavigateTo() to real <a>
elements so cards support middle-click, Ctrl+click, and
'Open in new tab'.
- CosplayerGrid.razor: replace <div> with <a href='/cosplayer/{id}'>
- AlbumCard.razor: add full-card <a> overlay, keep inner person <a>
- CosplayerGrid.razor.css + AlbumCard.razor.css: add display:block,
color:inherit, text-decoration:none for <a> card elements
- Remove OnCardClicked/OnNavigate callbacks and parent page
navigation methods (nav is now native via <a href>)
Closes#102
Replaces the hardcoded zero with a real query counting people
without a profile picture (ProfileAssetId == null).
Renamed from CosplayersMissingCover to CosplayersMissingProfile
to reflect the actual metric.
DTO, repository, and UI label updated accordingly.
fixes#97
AlbumService.GetAlbumsAsync, AssetService.GetAssetsAsync, PersonService.GetAllAsync
now default to PagedParametersDto.MaxPageSize (250) instead of hardcoded 30.
Also fixed AssetService.GetAssetsAsync page default from 1 to 0 for consistency
with zero-based pagination.
Replace inline AlbumPreviewDto construction in AlbumRepository.SearchQuery
with a call to the new ToAlbumPreviewDto(album, userId, accessLevel) mapper
overload, making the visibility logic reusable and the repository more compact.
- Remove unused using directives across C# and Razor files
- Remove unused IServiceProvider from SettingsRepository
- Simplify null/empty string checks in StatsRepository
- Add null-safe navigation for Albums/Tags in stats queries
- Initialize Asset.Hash default to prevent null refs
- Deduplicate AssetIds in AssetPicker
- Add OnStartedWaiting/OnFinishedWaiting/OnProgressChanged to Job
- Add global SearchDropdown component with keyboard nav
- Fix XML doc param mismatches
Resolved merge conflict in CosplayerDetail.razor:
- Kept SortFilterBar with instant search/sort (from feat/cosplayer-detail-search)
- Adapted allAlbums references to allAlbumsDict (from feature/global-search-dropdown)
- Kept updated PersonController.cs and PersonService.cs from both branches
Search now fires ReloadAlbums immediately on every keystroke, matching
the same instant behavior as Albums and Cosplayers pages. Since
ReloadAlbums only swaps the album grid content without touching
isLoading, focus is preserved and the page stays intact.
Add updateBanner parameter to LoadPerson so ReloadAlbums (triggered
by search/sort filter changes) does not regenerate the random banner
cover URLs, keeping the header fixed during filtering.
- Backend: accept PagedSearchParametersDto on GET /api/person/{id}
with in-memory search (case-insensitive title Contains) and sort
(name/created/updated/assets) before pagination
- Frontend service: add search, sortBy, sortAsc params to GetByIdAsync
- Frontend page: replace inline action buttons with reusable SortFilterBar
component, wire search/sort state into initial load and infinite scroll
Per review feedback: only Page being negative is truly invalid.
PageSize validation reverted to original < 0 (allowing 0).
PersonController keeps minimal Page < 0 check since it had none before.
JobsController aligned for consistency.