feat(anime): rename NFO Diagnostics to Anime Settings + add edit endpoints
Replaces the read-only 'NFO Diagnostics' page with a full per-anime
Settings page reached from the right-click context menu on series cards.
Users can now view and edit key, name, folder, tmdb_id, tvdb_id and site
for each anime; changes are persisted to the DB and optionally written
back to the NFO file or used to regenerate it.
Backend
- Rename NfoDiagnosticsResponse -> NfoSettingsResponse,
NfoSeriesDiagnostics -> NfoSeriesSettings
- Rename get_nfo_diagnostics -> get_nfo_settings,
repair_nfo -> repair_nfo_settings
- Fix nfo.py bug: repair was calling non-existent
update_series_nfo_status(); now uses update_nfo_status() and an
explicit AnimeSeriesService.update(nfo_path=...)
- New endpoints on /api/anime/{key}:
GET /settings -> AnimeSettingsResponse
PUT /settings -> AnimeSettingsResponse
(body: name/folder/tmdb_id/tvdb_id/site,
options: apply_to_nfo, rename_disk)
POST /regenerate-nfo -> AnimeSettingsRegenerateNfoResponse
- New Pydantic models: AnimeSettingsResponse,
AnimeSettingsUpdateRequest, AnimeSettingsRegenerateNfoResponse
- /anime/settings page route; /settings/nfo now 301-redirects to it
Frontend
- New AniWorld.AnimeSettingsManager JS module (single-page form,
no tabs) with public API init/loadSeries/saveSettings/regenerateNfo/
validateField/populateForm/showSaveSuccess/showError
- New anime-settings.html template + anime-settings.css
- Right-click menu: data-action 'nfo-diagnostics' replaced by
'anime-settings' (label 'Anime Settings'), navigates to
/anime/settings?key=...
- Library 'Open NFO Diagnostics' link renamed to 'Open Anime Settings'
Bug fix
- context-menu click handler was calling hide() BEFORE building the
navigation URL, which cleared currentSeriesKey to null and produced
/anime/settings?key=null. Captures the key into a local const first.
Regression-locked by tests/frontend/unit/context_menu.test.js.
Tests
- 21 new pytest tests in tests/api/test_anime_settings_endpoints.py
(GET/PUT/regenerate-nfo, auth, validation, nfo-repair bug regression)
- tests/api/test_nfo_endpoints.py trimmed to 6 focused tests
- 31 new Vitest unit tests for AnimeSettingsManager
- 5 new Vitest unit tests for ContextMenu (incl. source-invariant
regression guard for the hide()-before-key bug)
- 5 new Playwright E2E tests covering right-click, direct nav,
legacy /settings/nfo redirect, and context-menu labels
- New vitest.config.js (environment: happy-dom)
Docs
- Docs/API.md: new section 'Anime Settings Endpoints'
- Docs/CHANGELOG.md: documents the rename and the context-menu bug fix
Verified
- pytest: 27/27 (21 new + 6 trimmed nfo)
- vitest: 36/36 (31 anime-settings + 5 context-menu)
- playwright e2e: 5/5
This commit is contained in:
@@ -37,6 +37,72 @@ This changelog follows [Keep a Changelog](https://keepachangelog.com/) principle
|
||||
|
||||
---
|
||||
|
||||
## [Unreleased] - 2026-06-20
|
||||
|
||||
### Added
|
||||
|
||||
- **Anime Settings page** — renamed from "NFO Diagnostics". Right-click
|
||||
on any anime card → "Anime Settings" navigates to
|
||||
`/anime/settings?key=<series>`. The new page lets the user view and
|
||||
edit `name`, `folder`, `tmdb_id`, `tvdb_id`, and `site` directly in
|
||||
the database, with options to rename the on-disk folder and
|
||||
regenerate `tvshow.nfo` in one click.
|
||||
- **New API endpoints** under `/api/anime/{key}/`:
|
||||
- `GET /settings` — return full editable settings payload
|
||||
- `PUT /settings` — update fields with validation
|
||||
- `POST /regenerate-nfo` — regenerate `tvshow.nfo` from TMDB
|
||||
- **Pydantic models**: `AnimeSettingsResponse`,
|
||||
`AnimeSettingsUpdateRequest`, `AnimeSettingsRegenerateNfoResponse`
|
||||
in [src/server/models/anime.py](../src/server/models/anime.py).
|
||||
- **Frontend module**: `AniWorld.AnimeSettingsManager` IIFE in
|
||||
[src/server/web/static/js/pages/anime-settings.js](../src/server/web/static/js/pages/anime-settings.js)
|
||||
with public API: `init`, `loadSeries`, `saveSettings`,
|
||||
`regenerateNfo`, `validateField`, `populateForm`, `showSaveSuccess`,
|
||||
`showError`.
|
||||
- **Vitest JS unit tests** covering every public function on
|
||||
`AnimeSettingsManager` — 31 tests in
|
||||
[tests/frontend/unit/anime_settings.test.js](../tests/frontend/unit/anime_settings.test.js).
|
||||
- **Playwright E2E test** for the right-click → settings page flow in
|
||||
[tests/frontend/e2e/anime_settings_page.spec.js](../tests/frontend/e2e/anime_settings_page.spec.js).
|
||||
|
||||
### Changed
|
||||
|
||||
- **Right-click context menu** on the library page: "NFO Diagnostics"
|
||||
→ "Anime Settings" (`data-action="nfo-diagnostics"` →
|
||||
`data-action="anime-settings"`).
|
||||
- **Configuration modal link**: "Open NFO Diagnostics" → "Open Anime
|
||||
Settings", target URL `/settings/nfo` → `/anime/settings`.
|
||||
- **Page route**: `/settings/nfo` returns a 301 redirect to
|
||||
`/anime/settings` for backwards compatibility with bookmarks.
|
||||
- **Pydantic model rename** in [src/server/models/nfo.py](../src/server/models/nfo.py):
|
||||
- `NfoDiagnosticsResponse` → `NfoSettingsResponse`
|
||||
- `NfoSeriesDiagnostics` → `NfoSeriesSettings`
|
||||
- **Function rename** in [src/server/api/nfo.py](../src/server/api/nfo.py):
|
||||
- `get_nfo_diagnostics` → `get_nfo_settings`
|
||||
- `repair_nfo` → `repair_nfo_settings`
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Bug**: `src/server/api/nfo.py` called the non-existent
|
||||
`anime_service.update_series_nfo_status(...)` method, which would
|
||||
raise `AttributeError` after a successful NFO repair. Renamed the
|
||||
call to the existing `update_nfo_status(...)` method (matching its
|
||||
signature `(key, has_nfo, tmdb_id=None, tvdb_id=None, db=None)`)
|
||||
and added an explicit `AnimeSeriesService.update(db, id, nfo_path=...)`
|
||||
call to keep `nfo_path` in sync. Covered by regression tests in
|
||||
`TestBugFixCreateOrUpdateNfo`.
|
||||
|
||||
- **Bug**: Right-clicking a series card and choosing "Anime Settings"
|
||||
opened `/anime/settings?key=null` instead of carrying the series key.
|
||||
Root cause: the click handler in
|
||||
[src/server/web/static/js/index/context-menu.js](../src/server/web/static/js/index/context-menu.js)
|
||||
called `hide()` BEFORE building the URL — and `hide()` cleared
|
||||
`currentSeriesKey` to null. Fix captures the key into a local
|
||||
`const` before calling `hide()`. Regression-locked by
|
||||
`tests/frontend/unit/context_menu.test.js` (5 tests).
|
||||
|
||||
---
|
||||
|
||||
## [Unreleased] - 2026-06-05
|
||||
|
||||
### Fixed
|
||||
|
||||
Reference in New Issue
Block a user