@@ -17,8 +17,10 @@ import {
17
17
ReopenedEvent ,
18
18
ReviewEvent ,
19
19
TimelineEvent ,
20
+ UnassignEvent ,
20
21
} from '../../src/common/timelineEvent' ;
21
22
import { groupBy , UnreachableCaseError } from '../../src/common/utils' ;
23
+ import { IAccount , IActor } from '../../src/github/interface' ;
22
24
import { ReviewType } from '../../src/github/views' ;
23
25
import PullRequestContext from '../common/context' ;
24
26
import { CommentView } from './comment' ;
@@ -28,16 +30,32 @@ import { nbsp } from './space';
28
30
import { Timestamp } from './timestamp' ;
29
31
import { AuthorLink , Avatar } from './user' ;
30
32
33
+ function isAssignUnassignEvent ( event : TimelineEvent | ConsolidatedAssignUnassignEvent ) : event is AssignEvent | UnassignEvent {
34
+ return event . event === EventType . Assigned || event . event === EventType . Unassigned ;
35
+ }
36
+
37
+ interface ConsolidatedAssignUnassignEvent {
38
+ id : number ;
39
+ event : EventType . Assigned | EventType . Unassigned ;
40
+ assignees ?: IAccount [ ] ;
41
+ unassignees ?: IAccount [ ] ;
42
+ actor : IActor ;
43
+ createdAt : string ;
44
+ }
45
+
31
46
export const Timeline = ( { events, isIssue } : { events : TimelineEvent [ ] , isIssue : boolean } ) => {
32
- const consolidatedEvents : TimelineEvent [ ] = [ ] ;
47
+ const consolidatedEvents : ( TimelineEvent | ConsolidatedAssignUnassignEvent ) [ ] = [ ] ;
33
48
for ( let i = 0 ; i < events . length ; i ++ ) {
34
- if ( ( i > 0 ) && ( events [ i ] . event === EventType . Assigned ) && ( consolidatedEvents [ consolidatedEvents . length - 1 ] . event === EventType . Assigned ) ) {
35
- const lastEvent = consolidatedEvents [ consolidatedEvents . length - 1 ] as AssignEvent ;
36
- const newEvent = events [ i ] as AssignEvent ;
37
- if ( new Date ( lastEvent . createdAt ) . getTime ( ) + ( 1000 * 60 * 10 ) > new Date ( newEvent . createdAt ) . getTime ( ) ) { // within 10 minutes
38
- if ( lastEvent . assignees . every ( a => a . id !== newEvent . assignees [ 0 ] . id ) ) {
39
- lastEvent . assignees = [ ...lastEvent . assignees , ...newEvent . assignees ] ;
40
- }
49
+ if ( ( i > 0 ) && isAssignUnassignEvent ( events [ i ] ) && isAssignUnassignEvent ( consolidatedEvents [ consolidatedEvents . length - 1 ] ) ) {
50
+ const lastEvent = consolidatedEvents [ consolidatedEvents . length - 1 ] as ConsolidatedAssignUnassignEvent ;
51
+ const newEvent = events [ i ] as ConsolidatedAssignUnassignEvent ;
52
+ if ( ( lastEvent . actor . login === newEvent . actor . login ) && ( new Date ( lastEvent . createdAt ) . getTime ( ) + ( 1000 * 60 * 10 ) > new Date ( newEvent . createdAt ) . getTime ( ) ) ) { // within 10 minutes
53
+ const assignees = lastEvent . assignees || [ ] ;
54
+ const unassignees = lastEvent . unassignees || [ ] ;
55
+ const newAssignees = newEvent . assignees ?. filter ( a => ! assignees . some ( b => b . id === a . id ) ) ?? [ ] ;
56
+ const newUnassignees = newEvent . unassignees ?. filter ( a => ! unassignees . some ( b => b . id === a . id ) ) ?? [ ] ;
57
+ lastEvent . assignees = [ ...assignees , ...newAssignees ] ;
58
+ lastEvent . unassignees = [ ...unassignees , ...newUnassignees ] ;
41
59
lastEvent . createdAt = newEvent . createdAt ;
42
60
} else {
43
61
consolidatedEvents . push ( newEvent ) ;
@@ -58,7 +76,9 @@ export const Timeline = ({ events, isIssue }: { events: TimelineEvent[], isIssue
58
76
case EventType . Merged :
59
77
return < MergedEventView key = { `merged${ event . id } ` } { ...event } /> ;
60
78
case EventType . Assigned :
61
- return < AssignEventView key = { `assign${ event . id } ` } event = { event } isIssue = { isIssue } /> ;
79
+ return < AssignUnassignEventView key = { `assign${ event . id } ` } event = { event } /> ;
80
+ case EventType . Unassigned :
81
+ return < AssignUnassignEventView key = { `unassign${ event . id } ` } event = { event } /> ;
62
82
case EventType . HeadRefDeleted :
63
83
return < HeadDeleteEventView key = { `head${ event . id } ` } { ...event } /> ;
64
84
case EventType . CrossReferenced :
@@ -344,9 +364,22 @@ function joinWithAnd(arr: JSX.Element[]): JSX.Element {
344
364
return < > { arr . slice ( 0 , - 1 ) . map ( item => < > { item } , </ > ) } and { arr [ arr . length - 1 ] } </ > ;
345
365
}
346
366
347
- const AssignEventView = ( { event, isIssue } : { event : AssignEvent , isIssue : boolean } ) => {
348
- const { actor, assignees } = event ;
367
+ const AssignUnassignEventView = ( { event } : { event : AssignEvent | UnassignEvent | ConsolidatedAssignUnassignEvent } ) => {
368
+ const { actor } = event ;
369
+ const assignees = ( event as AssignEvent ) . assignees || [ ] ;
370
+ const unassignees = ( event as UnassignEvent ) . unassignees || [ ] ;
349
371
const joinedAssignees = joinWithAnd ( assignees . map ( a => < AuthorLink key = { a . id } for = { a } /> ) ) ;
372
+ const joinedUnassignees = joinWithAnd ( unassignees . map ( a => < AuthorLink key = { a . id } for = { a } /> ) ) ;
373
+
374
+ let message : JSX . Element ;
375
+ if ( assignees . length > 0 && unassignees . length > 0 ) {
376
+ message = < > assigned { joinedAssignees } and unassigned { joinedUnassignees } </ > ;
377
+ } else if ( assignees . length > 0 ) {
378
+ message = < > assigned { joinedAssignees } </ > ;
379
+ } else {
380
+ message = < > unassigned { joinedUnassignees } </ > ;
381
+ }
382
+
350
383
return (
351
384
< div className = "comment-container commit" >
352
385
< div className = "commit-message" >
@@ -355,9 +388,7 @@ const AssignEventView = ({ event, isIssue }: { event: AssignEvent, isIssue: bool
355
388
</ div >
356
389
< AuthorLink for = { actor } />
357
390
< div className = "message" >
358
- { isIssue
359
- ? < > assigned { joinedAssignees } </ >
360
- : < > assigned { joinedAssignees } to this pull request</ > }
391
+ { message }
361
392
</ div >
362
393
</ div >
363
394
< Timestamp date = { event . createdAt } />
0 commit comments