1+ import React from 'react'
2+ import '@primer/primitives/dist/css/functional/themes/light.css'
3+ import { BaseStyles , ThemeProvider , Timeline } from '@primer/react'
4+ import { FeedPullRequestClosedIcon , CommentIcon , FeedMergedIcon , IssueReopenedIcon } from '@primer/octicons-react'
5+ import MRComment from '@/components/MrView/MRComment' ;
6+ import { formatDistance , fromUnixTime } from 'date-fns' ;
7+ import { MRDetail } from '@/pages/[org]/mr/[id]' ;
8+
9+ interface TimelineItemProps {
10+ badge ?: React . ReactNode
11+ children ?: React . ReactNode
12+ isOver ?: boolean
13+ }
14+
15+ interface ConvItem {
16+ id : number
17+ badge ?: React . ReactNode
18+ children ?: React . ReactNode
19+ isOver : boolean ;
20+ }
21+
22+ interface TimelineWrapperProps {
23+ convItems ?: ConvItem [ ] ;
24+ }
25+
26+
27+ const TimelineItem = ( { badge, children, isOver } : TimelineItemProps ) => {
28+ return (
29+ < >
30+ < Timeline . Item >
31+ < Timeline . Badge > { badge } </ Timeline . Badge >
32+ < Timeline . Body > { children } </ Timeline . Body >
33+ </ Timeline . Item >
34+ { isOver && < Timeline . Break /> }
35+ </ >
36+ )
37+ }
38+
39+ const TimelineWrapper : React . FC < TimelineWrapperProps > = ( { convItems = [ ] } ) => {
40+ return (
41+ < ThemeProvider >
42+ < BaseStyles >
43+ < Timeline clipSidebar >
44+ { convItems ?. map ( ( item ) => (
45+ < TimelineItem key = { item . id } badge = { item . badge } isOver = { item . isOver } >
46+ { item . children }
47+ </ TimelineItem >
48+ ) ) }
49+ </ Timeline >
50+ </ BaseStyles >
51+ </ ThemeProvider >
52+ ) ;
53+ } ;
54+
55+ const TimelineItems : React . FC < { mrDetail ?: MRDetail , id : string } > = ( { mrDetail, id } ) => {
56+ if ( ! mrDetail ) {
57+ return null ;
58+ }
59+
60+ const convItems : ConvItem [ ] = mrDetail ?. conversations . map ( ( conv ) => {
61+ let icon ;
62+ let children ;
63+ let isOver = false ;
64+
65+ switch ( conv . conv_type ) {
66+ case 'Comment' :
67+ icon = < CommentIcon /> ;
68+ children = < MRComment conv = { conv } id = { id } whoamI = "mr" /> ;
69+ break ;
70+ case 'Merged' :
71+ icon = < FeedMergedIcon size = { 24 } className = "text-purple-500" /> ;
72+ children =
73+ 'Merged via the queue into main ' +
74+ formatDistance ( fromUnixTime ( conv . created_at ) , new Date ( ) , { addSuffix : true } ) ;
75+ isOver = true ;
76+ break ;
77+ case 'Closed' :
78+ icon = < FeedPullRequestClosedIcon size = { 24 } className = "text-red-500" /> ;
79+ children = conv . comment ;
80+ isOver = true ;
81+ break ;
82+ case 'Reopen' :
83+ icon = < IssueReopenedIcon /> ;
84+ children = conv . comment ;
85+ break ;
86+ }
87+
88+ return { badge : icon , children, isOver, id : conv . id } ;
89+ } ) ;
90+
91+ return < TimelineWrapper convItems = { convItems } /> ;
92+ } ;
93+
94+ export default TimelineItems ;
0 commit comments