PT-3976: Add ResourcePickerDialog to platform-bible-react and register as paranext-core dialog#2260
Open
captaincrazybro wants to merge 26 commits into
Open
PT-3976: Add ResourcePickerDialog to platform-bible-react and register as paranext-core dialog#2260captaincrazybro wants to merge 26 commits into
captaincrazybro wants to merge 26 commits into
Conversation
e20435d to
e21d125
Compare
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Creates the ResourcePickerDialog React component in platform-bible-react
with search filtering, language filtering, and three conditional sections
(already selected, installed, available to download). Adapts test traversal
to use closest('tr') for table row button lookup. All 11 tests pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add localization strings to en.json and es.json - Make allResources optional to fix DialogDefinition type compatibility - Remove table row borders and hover highlights - Fix non-null assertion ESLint violations in tests - Add JSDoc to exported component types - Fix z-index on MultiSelectComboBox in Storybook - Rebuild platform-bible-react dist Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Regenerate papi.d.ts (allResources now correctly optional) - Fix en.json key ordering (resourcePicker* before resources_deprecated_any) - Extract ResourceSection component to eliminate duplicated JSX - Fix NoResults story to use allResources: [] for true empty state - Fix sentence case: "Already selected", "Available to download", "Resource picker" - Remove hover:tw-bg-transparent from TableCell (restore standard hover highlight) - Fix ellipsis in search placeholder (... → …) across en.json, es.json, stories, test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Create resource-picker-dialog.utils.test.ts with 4 test cases - Tests check initial state, pagination, reset on item change, and hasMore flag - Tests use Vitest mocks for IntersectionObserver - All tests fail as expected (module not found) - RED phase of TDD Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…to Download section
…fecycle and add missing negative test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…language picker - Add missing Spanish translation for %resourcePicker_language_filter_multipleSelected% - Fix customLanguageSelectText useMemo missing anyLanguageText and localizedStrings deps - Remove redundant `as IntersectionObserverEntry` casts in utils test - Add JSDoc to useProgressiveList documenting sentinelRef placement and memoization contract - Add aria-hidden to scroll sentinel div - Add explicit name to LargeResourceList Storybook story - Regenerate dist build artifacts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3b01b9c to
875ffb8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Code Review Summary — Round 2
Branch: pt-3976-shared-resource-picker-ui
Base: origin/main
Date: 2026-05-13
Review model: Claude Sonnet 4.6
Files changed: 19
Overview
This round adds a
useProgressiveListhook backed byIntersectionObserverto the "Available to Download" section ofResourcePickerDialog, rendering items 50 at a time as the user scrolls rather than all at once. ALargeResourceListStorybook story demonstrates the optimization at 2500 entries. The PR also enhances the language filter with a multi-selectMultiSelectComboBoxthat shows custom summary text (%resourcePicker_language_filter_multipleSelected%) when multiple languages are chosen. Several issues were caught and fixed during review, including a missing Spanish translation, staledist/artifacts, a missingeslint-disableexplanation, missing useMemo deps, redundant type casts, and a missingaria-hiddenon the scroll sentinel.API Changes
useProgressiveList<T>(items, pageSize?)— new exported hook fromlib/platform-bible-react, returns{ visibleItems, sentinelRef, hasMore }LARGE_SAMPLE_RESOURCES— new exported constant (2500 generatedDblResourceDataentries) fromresource-picker-dialog.data.tsen.jsonandes.json:%resourcePicker_language_filter_any%,%resourcePicker_language_filter_multipleSelected%,%resourcePicker_showing_count%Findings
Important — Fixed During Review
assets/localization/es.json:%resourcePicker_language_filter_multipleSelected%was added toen.jsonbut missing fromes.json. (fixed: added"{selectCount} idiomas")resource-picker-dialog.component.tsx:customLanguageSelectTextuseMemo dependency array omittedanyLanguageTextandlocalizedStrings. (fixed: added both to deps)resource-picker-dialog.utils.test.ts: Threeas IntersectionObserverEntrycasts were redundant —ioCallbackis already typed asPartial<IntersectionObserverEntry>[]. (fixed: removed all three casts)resource-picker-dialog.utils.ts:eslint-disable-next-line no-null/no-nullhad no explanatory comment. (fixed by author: added explanation)lib/platform-bible-react/dist/: Build artifacts were stale, missing new hook export and localization key. (fixed by author: rannpm run build)resource-picker-dialog.utils.ts:useProgressiveListhad no JSDoc — sentinel placement constraint and memoization requirement were undocumented. (fixed: added full JSDoc)resource-picker-dialog.component.tsx: Scroll sentinel<div ref={sentinelRef} />was not hidden from assistive technology. (fixed: addedaria-hidden)resource-picker-dialog.stories.tsx:LargeResourceListstory had no explicit name; purpose was not clear from auto-generated label. (fixed: addedname: 'Large Resource List (2500 entries)')Important — Deferred by Author
Minor — No Action Taken
toDownloaduseMemo may be missingselectedLanguagesdepLARGE_SAMPLE_RESOURCESgenerated at module load time (minor test startup cost)useProgressiveListnot re-exported from library barrel (author: internal API, not needed)Positive Observations
useProgressiveListin its ownutils.tswith 5 focused unit testssentinelRefnull guard (if (el) observer.observe(el)) handles jsdom environment in tests without special-casingSuggested Review Focus
toDownloaduseMemo deps: ShouldselectedLanguagesbe in the dependency array?Code Review Summary — Round 1
Branch: pt-3976-shared-resource-picker-ui
Base: origin/main
Date: 2026-05-12
Review model: Claude Sonnet 4.6
Files changed: 18
Overview
This branch adds a
ResourcePickerDialogcomponent toplatform-bible-reactand registers it as a new dialog inparanext-core. The component is a presentational dialog that displays DBL resources in three sections — Already selected, Installed, and Available to download — and supports text search and language filtering. It is intended to be consumed by upcoming tickets that let users choose resources to support Bible translation.The implementation follows established platform patterns: a pure presentational component in
platform-bible-reactreceives all data via props with no PAPI coupling, while a thin wrapper inparanext-corewires upuseLocalizedStringsand registers the dialog via the existingDIALOGSmap. Several issues were caught and fixed during review, including a stalepapi.d.ts, alphabetical ordering violations in localization files, duplicate JSX sections, a broken Storybook story, and title-case violations.API Changes
lib/platform-bible-react— AddedResourcePickerDialogcomponent (default export)lib/platform-bible-react— AddedResourcePickerDialogPropstype exportlib/platform-bible-react— AddedResourcePickerDialogLocalizedStringstype exportlib/platform-bible-react— AddedRESOURCE_PICKER_DIALOG_STRING_KEYSconstant export (9 localization keys)papi.d.ts/dialog-definition.modelmodule — AddedRESOURCE_PICKER_DIALOG_TYPEconstant ('platform.resourcePicker')papi.d.ts/dialog-definition.modelmodule — AddedResourcePickerDialogOptionstype (allResources?: DblResourceData[],resourceType?: ResourceType,selectedResourceIds?: string[])papi.d.ts/dialog-definition.modelmodule — Added[RESOURCE_PICKER_DIALOG_TYPE]: DialogDataTypes<ResourcePickerDialogOptions, DblResourceData>entry toDialogTypesinterfaceFindings
Critical — Must address before merge
lib/papi-dts/papi.d.ts:allResourceswas typed as required (DblResourceData[]) but the sourcedialog-definition.model.tsdeclares it optional (DblResourceData[]?). The file had been hand-edited rather than regenerated, causing the published type contract to diverge from the implementation. (fixed during review: regeneratedpapi.d.tsvianpm run build:types;allResourcesis now correctly optional)Important — Should address before merge
DblResourceDataandResourceTypeare not re-exported from@papi/core. Extension developers usingshowDialog('platform.resourcePicker', ...)or consumingDialogTypes['platform.resourcePicker']will need these types. They are accessible viaplatform-bible-utils, but discoverability from@papi/corewould follow the existing pattern used for types likeLocalizeKey. Consider adding re-exports from theplatform-bible-utilsgroup in@papi/core.assets/localization/en.json: The nine%resourcePicker_*%keys were inserted after%resources_deprecated_any%, but alphabeticallyresourcePsorts beforeresources. (fixed during review)resource-picker-dialog.component.tsx: TheinstalledandtoDownloadJSX sections were structurally identical (~60 lines of duplicated JSX). (fixed during review: extractedResourceSectioncomponent)(author dismissed)resource-picker-dialog.component.test.tsx: The language filter has no unit test coverage.resource-picker-dialog.stories.tsx: TheNoResultsstory did not render the no-results state. (fixed during review)hover:tw-bg-transparentonTableCellsuppressed row hover highlight. (fixed during review)Minor
(dismissed)tw-z-[200]raw z-index valueNo(dismissed)DialogDescription(acknowledged, left for reviewer){fullName} ({displayName})not localizable…vs...in search placeholder (fixed during review)No cancel button(intentional)"Use" label for uninstalled resources(deferred)Suggested Review Focus
DblResourceData/ResourceTypediscoverability from@papi/coreFull Name (Abbrev)format localizabilityThis change is