Skip to content

feat: migrate ItemDetails and Comment components from Angular to React + TypeScript#249

Open
devin-ai-integration[bot] wants to merge 4 commits into
masterfrom
devin/1778794643-angular-to-react-migration
Open

feat: migrate ItemDetails and Comment components from Angular to React + TypeScript#249
devin-ai-integration[bot] wants to merge 4 commits into
masterfrom
devin/1778794643-angular-to-react-migration

Conversation

@devin-ai-integration
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot commented May 14, 2026

Summary

Migrates the item-details Angular module (ItemDetailsComponent + CommentComponent) to React functional components with TypeScript, following the Angular → React mapping rules specified in the task.

5 new files created (original Angular files preserved alongside):

File Purpose
src/app/item-details/ItemDetails.tsx Main component — replaces item-details.component.ts + .html
src/app/item-details/ItemDetails.module.scss CSS Modules styles (camelCase class names)
src/app/item-details/comment/Comment.tsx Recursive comment tree — replaces comment.component.ts + .html
src/app/item-details/comment/Comment.module.scss CSS Modules styles (camelCase class names)
src/app/shared/utils/formatCommentCount.ts Utility function replacing the comment pipe

Key conversions applied:

  • @Component + template → functional component with inline JSX
  • ngOnInit + route.params.subscribe()useEffect + useParams() (react-router-dom v6)
  • HackerNewsAPIService (DI) → plain fetch with useEffect + useState + AbortController cleanup
  • SettingsService (DI) → useSettings() hook (React Context)
  • _location.back()useNavigate()navigate(-1)
  • *ngIf / *ngFor → conditional && / .map()
  • [innerHTML]dangerouslySetInnerHTML
  • [ngStyle] → inline style object
  • [class.X]="cond" → template literal class concatenation
  • [routerLink]<Link to="...">
  • @Input() → typed Props interface
  • comment pipe → formatCommentCount() utility
  • SubscriptionAbortController cleanup in useEffect
  • SCSS styleUrls → CSS Modules (.module.scss)
  • (click)onClick

All existing behavior preserved: loading state, error state, scroll-to-top, back navigation, poll rendering with vote bars, recursive comment tree with collapse/expand, conditional link targets (_blank), deleted comment handling.

Review & Testing Checklist for Human

  • Verify ItemDetails.tsx correctly fetches and displays story content including title, points, user, time_ago, domain, and comments
  • Verify poll rendering works correctly — poll bars width should be proportional to vote count
  • Verify the recursive Comment component handles deeply nested comment trees and collapse/expand toggle
  • Verify formatCommentCount returns "discuss" for 0, "1 comment" for 1, and "N comments" for N > 1
  • Verify CSS Modules class names use camelCase (per repo knowledge: "always use camel case")

Recommended test plan:

  1. Set up a React + React Router v6 environment and wire ItemDetails as a route at /item/:id
  2. Provide a SettingsContext with useSettings() hook, and stub Loader/ErrorMessage components
  3. Navigate to /item/<valid-hn-item-id> and verify full rendering
  4. Test a poll item, a job item, and a story with nested comments
  5. Test back button navigation and collapse/expand on comments

Notes

  • The original Angular files are intentionally kept so both implementations can be compared side-by-side
  • The new React files reference useSettings, Loader, and ErrorMessage imports — these would need to be created as part of the broader migration effort (they are the React equivalents of the existing Angular shared components)
  • The Story and Comment models are imported from the existing shared models (Angular classes), which should be converted to TS interfaces as part of the full migration

Link to Devin session: https://app.devin.ai/sessions/e966af3e2bda440d801d01a782a95eca
Requested by: @charityquinn-cognition


Devin Review

Status Commit
⚪ Not started

Run Devin Review

💡 Connect your GitHub account to enable automatic code reviews.

Open in Devin Review (Staging)
Open in Devin Review

…t + TypeScript

- Convert ItemDetailsComponent to React functional component (ItemDetails.tsx)
- Convert CommentComponent to React functional component (Comment.tsx)
- Replace Angular DI with useParams, useNavigate, useSettings hooks
- Replace comment pipe with formatCommentCount utility function
- Convert SCSS to CSS Modules (camelCase class names)
- Preserve all behavior: loading, error, scroll-to-top, back nav, polls, recursive comments
- Original Angular files kept alongside for comparison

Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>
@devin-ai-integration
Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

devin-ai-integration[bot]

This comment was marked as resolved.

Adds .catch() to Promise.all(pollPromises) to handle network errors
and AbortError on unmount, preventing unhandled promise rejections
and perpetual loading spinners.

Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>
devin-ai-integration[bot]

This comment was marked as resolved.

- Nest bare p/a selectors inside .item in ItemDetails.module.scss
- Wrap bare a selector in .commentWrapper in Comment.module.scss
- Add commentWrapper class to Comment.tsx root div
- Guard poll bar width calculation against division by zero

Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>
devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant