Follow-up to #2141 (merged). Three operator-reported problems with the shipped import auto-translate feature, plus a real bug found while testing them. ## 1. The settings were unfindable > "where are the translate settings? I can't find them and search in settings isn't finding them" The controls rendered fine — but Settings **search** only matches curated keywords and advertised i18n keys per section, and "Project General" says nothing about translation. So searching `translate` matched nothing. Now advertised on **Project General** (where the controls live) and on **Project/Global Models** (where the lane is picked). Verified against the real `filterSettingsSectionsForSearch`, not by eye: | query | surfaces | |---|---| | `translate` / `translation` | general, project-models, global-models | | `auto translate`, `target language` | general | For reference, they live in **Settings → Project General**, directly below "Always link imported GitHub issues to GitHub tracking". ## 2. The checkbox looked foreign > "the auto translate checkbox needs to be the left of the text and it needs to be styled like other check boxes" It used `SettingsToggleRow`, which renders a **right-aligned toggle switch**, while every other GitHub/import setting in that section uses a plain `checkbox-label` with the input **before** its text. Two checkbox idioms in one section read as a bug regardless of which is nicer in isolation. Both controls now use the section's native `form-group` + `checkbox-label` / `select.select` markup. A test asserts my checkbox's class and structure are **identical to the neighbouring `githubLinkImportedIssuesToTracking` checkbox**, so it can't silently drift back. ## 3. Auto-translation was async but not incremental > "ensure the auto translate is non blocking and runs async in the background" The list never blocked (it rendered originals immediately; import is cache-read only). But a **single request translated all 50 issues**, so nothing appeared until every issue finished — minutes on a large page — and one timeout discarded the whole page's work. It now streams in chunks of 8: titles appear as each chunk lands, a failure costs one chunk instead of the page, and chunks are sequential so opening the panel can't fan 50 model calls at the provider at once. ## Also: a real infinite-render loop (found by testing #3) `items` and `eligible` are fresh **array identities** on most renders, and both sat in the effect's dependency list — effect → `setState` → re-render → new array → effect. It manifested as a **heap OOM** under `renderHook`. Effect dependencies are now string/scalar only, with live issue data read from a ref, and the reset path preserves state identity so it cannot re-trigger itself. This bug shipped in #2141; it needed a re-render with a fresh `issues` identity to trigger, but it was live. ## Changeset Folded into the **existing unreleased** `github-import-auto-translate` changeset rather than adding a second one for the same unshipped feature. ## Verification - ✅ `pnpm lint`, root `pnpm typecheck`, `pnpm verify:fast`, `pnpm test:gate` (479 tests) - ✅ 54 tests across the translate suites, including new coverage pinning the checkbox idiom + neighbour parity, and that translations **stream per chunk** rather than all-or-nothing (a regression to one request fails these) ## Reviewer note Worth knowing for future test-writing here: `beforeEach(() => mock.mockReset())` **implicitly returns the mock**, and vitest treats a function returned from `beforeEach` as a teardown callback — it then invokes the mock with zero arguments and corrupts `mock.calls`. The test file uses a block body and says why. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added project settings to enable GitHub import auto-translation and choose a target language, including “follow dashboard language”. * Auto-translation now runs in the background, chunked, and streams translated issue content progressively into imported tasks. * Translations are cached and reused to speed up repeated imports, with incremental updates shown as they arrive. * Settings search now includes translation and import auto-translation terms. * **Bug Fixes** * Improved update handling so changes to issue text refresh translations, while closed issues are never requested and failures don’t erase already translated results. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1.4 KiB
@runfusion/fusion
| @runfusion/fusion |
|---|
| minor |
summary: Auto-translate foreign-language GitHub issues in the Import Tasks panel, with a target language and model you choose.
category: feature
dev: New project settings githubImportAutoTranslate (default false) and importTranslateTargetLocale, plus an import-translate model lane (project importTranslateProvider/importTranslateModelId, global importTranslateGlobalProvider/importTranslateGlobalModelId) resolved by resolveImportTranslateSettingsModel. Translations persist in the new project.import_translation_cache table (migration 0010) keyed by project+repo+issue+locale+source hash, and are pruned when an issue closes. POST /api/github/issues/auto-translate translates the 50 most recent open foreign issues per load on its own rate-limit budget; both single and batch import read the cache so imported tasks carry the translated title/body. Language detection moved from the dashboard app to @fusion/core so the panel and server share one heuristic. Auto-translation runs in the background and streams in chunks of 8 (AUTO_TRANSLATE_CHUNK_SIZE), so list titles fill in progressively and one failed chunk cannot discard the page; nothing in the panel awaits it. The two controls live in Settings -> Project General using that section's native checkbox/select markup, and Settings search advertises translation terms for General plus the Project/Global Models lane.