@@ -6,21 +6,21 @@ import {
66 Chip ,
77 Typography ,
88 AccordionDetails ,
9- Box
9+ Box ,
10+ Card ,
11+ CardContent ,
1012} from '@mui/material' ;
13+ import { Link } from 'react-router-dom' ;
1114import ExpandMoreIcon from '@mui/icons-material/ExpandMore' ;
1215import { getAvatarURL } from '../../../api/api.js' ;
1316import { AppContext } from '../../../context/AppContext.jsx' ;
1417import { selectCheckinsForMember } from '../../../context/selectors.js' ;
1518import {
1619 isPastCheckin ,
1720 getCheckinDate ,
18- getQuarterBeginEndWithGrace ,
19- getCheckinDateForPeriod ,
20- getLastCheckinDate ,
2121 statusForPeriodByMemberScheduling
2222} from './checkin-utils.js' ;
23- import LinkSection from './LinkSection.jsx ' ;
23+ import { getQuarterBeginEnd } from '../../../helpers ' ;
2424import './TeamMemberMap.css' ;
2525
2626const SortOption = {
@@ -33,13 +33,14 @@ const TeamMemberMap = ({ members, closed, planned, reportDate }) => {
3333 const [ sortBy , setSortBy ] = useState ( SortOption . BY_MEMBER ) ;
3434
3535 const epoch = new Date ( 0 ) ;
36- const pdls = members . reduce ( ( map , member ) => {
37- if ( member . pdlId && ! map [ member . pdlId ] ) {
38- map [ member . pdlId ] = members . find ( ( m ) => m . id === member . pdlId ) ;
39- }
36+ const memberMap = members . reduce ( ( map , member ) => {
37+ map [ member . id ] = member ;
4038 return map ;
4139 } , { } ) ;
4240
41+ const linkStyle = { textDecoration : 'none' } ;
42+ const checkinPath = ( member , checkin ) => `/checkins/${ member . id } /${ checkin . id } ` ;
43+
4344 const sortByName = ( left , right ) => {
4445 if ( left && right ) {
4546 return `${ left . lastName } ${ left . firstName } ` . localeCompare (
@@ -50,34 +51,32 @@ const TeamMemberMap = ({ members, closed, planned, reportDate }) => {
5051 } ;
5152
5253 const sortByPDLName = ( a , b ) =>
53- sortByName ( pdls [ a . reportDatePDLId ] , pdls [ b . reportDatePDLId ] ) ;
54+ sortByName ( memberMap [ a . reportDatePDLId ] , memberMap [ b . reportDatePDLId ] ) ;
5455
5556 // We're going to cache the checkins into the member data structures so that
5657 // we can properly sort by PDL when the PDL, in the past, is different than
5758 // the current PDL.
58- const { startOfQuarter, endOfQuarter } = getQuarterBeginEndWithGrace ( reportDate ) ;
59+ const { startOfQuarter, endOfQuarter } = getQuarterBeginEnd ( reportDate ) ;
5960 members . map ( member => {
60- const checkins = selectCheckinsForMember (
61+ member . checkins = selectCheckinsForMember (
6162 state ,
6263 member . id ,
6364 ) . filter ( checkin => closed || ! checkin . completed )
64- . filter ( checkin => planned || isPastCheckin ( checkin ) ) ;
65- member . checkins = checkins ;
65+ . filter ( checkin => planned || isPastCheckin ( checkin ) )
66+ . filter ( checkin => ( getCheckinDate ( checkin ) <= endOfQuarter ) ) ;
6667
6768 // If there are checkins, we're going to sort them with the latest
6869 // first. Since the member's PDL could have changed since the last
6970 // checkin, we are going to use the PDL id of the checkin instead
7071 // of the current PDL. They may be the same, but again they may not.
72+ member . checkin = null ;
7173 member . reportDatePDLId = member . pdlId ;
72- if ( checkins . length > 0 ) {
73- checkins . sort ( ( a , b ) => getCheckinDate ( b ) - getCheckinDate ( a ) ) ;
74-
75- for ( let checkin of checkins ) {
76- const checkinDate = getCheckinDate ( checkin ) ;
77- if ( checkinDate >= startOfQuarter && checkinDate <= endOfQuarter ) {
78- member . reportDatePDLId = checkin . pdlId ;
79- break ;
80- }
74+ if ( member . checkins . length > 0 ) {
75+ member . checkins . sort ( ( a , b ) => getCheckinDate ( b ) - getCheckinDate ( a ) ) ;
76+ const checkin = member . checkins [ 0 ] ;
77+ if ( getCheckinDate ( checkin ) >= startOfQuarter ) {
78+ member . checkin = checkin ;
79+ member . reportDatePDLId = member . checkin . pdlId ;
8180 }
8281 }
8382 } ) ;
@@ -105,18 +104,10 @@ const TeamMemberMap = ({ members, closed, planned, reportDate }) => {
105104 </ Box >
106105 {
107106 members . map ( member => {
108- const pdl = pdls [ member . reportDatePDLId ] ;
109- const checkins = member . checkins ;
110-
107+ const pdl = memberMap [ member . reportDatePDLId ] ;
111108 return (
112- < Accordion
113- key = { member . id }
114- className = "team-member-map-accordion"
115- >
116- < AccordionSummary
117- expandIcon = { < ExpandMoreIcon /> }
118- className = "team-member-map-accordion-summary"
119- >
109+ < Card key = { member . id } className = "team-member-map-row" >
110+ < CardContent className = "team-member-map-row-summary" >
120111 < Avatar
121112 sx = { { width : 54 , height : 54 } }
122113 src = { getAvatarURL ( member . workEmail ) }
@@ -148,36 +139,30 @@ const TeamMemberMap = ({ members, closed, planned, reportDate }) => {
148139 < Typography
149140 variant = "caption"
150141 component = { 'time' }
151- dateTime = { getLastCheckinDate ( checkins ) . toISOString ( ) }
142+ dateTime = { getCheckinDate ( member . checkin ) . toISOString ( ) }
152143 sx = { { display : { xs : 'none' , sm : 'none' , md : 'grid' } } }
153144 className = "team-member-map-summmary-latest-activity"
154145 >
155146 < Box sx = { { display : 'flex' , flexDirection : 'column' } } >
156- { getCheckinDateForPeriod (
157- checkins ,
158- reportDate
159- ) . getFullYear ( ) === epoch . getFullYear ( ) ? (
147+ { member . checkin == null ? (
160148 < Typography component = "nobr" variant = "h6" >
161149 No activity yet{ ' ' }
162150 < span role = "img" aria-label = "unscheduled" >
163151 🚫
164152 </ span >
165153 </ Typography >
166154 ) : (
167- < >
155+ < Link style = { linkStyle }
156+ to = { checkinPath ( member , member . checkin ) } >
168157 < Typography component = "nobr" variant = "h6" >
169- { getCheckinDateForPeriod (
170- checkins ,
171- reportDate
172- ) . toLocaleDateString ( navigator . language , {
158+ { getCheckinDate ( member . checkin )
159+ . toLocaleDateString ( navigator . language , {
173160 year : 'numeric' ,
174161 month : '2-digit' ,
175162 day : 'numeric'
176163 } ) } { ' ' }
177- { getCheckinDateForPeriod (
178- checkins ,
179- reportDate
180- ) . getTime ( ) > new Date ( ) . getTime ( ) ? (
164+ { getCheckinDate ( member . checkin )
165+ . getTime ( ) > new Date ( ) . getTime ( ) ? (
181166 < span role = "img" aria-label = "scheduled" >
182167 📆
183168 </ span >
@@ -187,38 +172,36 @@ const TeamMemberMap = ({ members, closed, planned, reportDate }) => {
187172 </ span >
188173 ) }
189174 </ Typography >
190- </ >
175+ </ Link >
191176 ) }
177+ { member . checkin == null && member . checkins . length > 0 &&
178+ < span > Last Activity: {
179+ < Link style = { linkStyle }
180+ to = { checkinPath ( member , member . checkins [ 0 ] ) } >
181+ { getCheckinDate ( member . checkins [ 0 ] ) . toString ( )
182+ . split ( ' ' ) . slice ( 0 , 5 ) . join ( ' ' ) }
183+ </ Link > }
184+ </ span >
185+ }
192186 </ Box >
193187 </ Typography >
194188 < Chip
195189 label = { statusForPeriodByMemberScheduling (
196- checkins ,
190+ member . checkin ,
197191 reportDate
198192 ) }
199193 color = {
200194 statusForPeriodByMemberScheduling (
201- checkins ,
195+ member . checkin ,
202196 reportDate
203197 ) === 'Done'
204198 ? 'secondary'
205199 : 'primary'
206200 }
207201 />
208202 </ div >
209- </ AccordionSummary >
210- < AccordionDetails id = "accordion-checkin-date" >
211- { checkins . length === 0
212- ? 'No check-in activity found for this member and PDL.'
213- : checkins . map ( checkin => (
214- < LinkSection
215- key = { checkin . id }
216- checkin = { checkin }
217- member = { member }
218- />
219- ) ) }
220- </ AccordionDetails >
221- </ Accordion >
203+ </ CardContent >
204+ </ Card >
222205 ) ;
223206 } )
224207 }
0 commit comments