1- import { ComponentProps , ReactNode , useState } from 'react' ;
1+ import { ReactNode } from 'react' ;
22import moment from 'moment' ;
33import classNames from 'classnames' ;
44import { Avatar , Collapsible , Icon , Stack , useToggle } from '@openedx/paragon' ;
55import { KeyboardArrowDown , KeyboardArrowUp } from '@openedx/paragon/icons' ;
6- import { FormattedMessage , useIntl } from '@edx/frontend-platform/i18n' ;
6+ import { useIntl } from '@edx/frontend-platform/i18n' ;
77
88import { useLibraryPublishHistoryEntries } from '@src/library-authoring/data/apiHooks' ;
99import { LoadingSpinner } from '@src/generic/Loading' ;
1010
11- import { LibraryHistoryEntry , LibraryPublishContributor , LibraryPublishHistoryGroup } from '../../data/api' ;
11+ import { LibraryHistoryEntry , LibraryPublishHistoryGroup } from '../../data/api' ;
1212import messages from './messages' ;
1313import { getItemIcon } from '@src/generic/block-type-utils' ;
14-
15- const MAX_VISIBLE_CONTRIBUTORS = 5 ;
14+ import { ContributorsAvatars } from './ContributorAvatars' ;
15+ import { HistoryLogGroupEntries } from './HistoryLogGroupEntries' ;
1616
1717export interface HistoryLogGroupTitleProps {
1818 titleMessage : string | ReactNode ;
@@ -34,47 +34,13 @@ export interface HistoryDraftLogGroupProps {
3434 entries : LibraryHistoryEntry [ ] ;
3535}
3636
37- export interface HistoryLogGroupEntriesProps {
38- entries : LibraryHistoryEntry [ ] ;
39- }
40-
4137export interface HistoryPublishLogGroupProps extends LibraryPublishHistoryGroup {
4238 itemId : string ;
4339 // When true, hides the vertical connector line rendered below this group. Used for the last group
4440 // in the history log to avoid a dangling connector with nothing below it.
4541 hideLogVert ?: boolean ;
4642}
4743
48- interface ContributorAvatarProps {
49- username ?: string ;
50- src ?: string ;
51- className : string ;
52- size : ComponentProps < typeof Avatar > [ 'size' ] ;
53- }
54-
55- interface ContributorsAvatarsProps {
56- contributors : LibraryPublishContributor [ ] ;
57- }
58-
59- const ContributorAvatar = ( {
60- username,
61- src,
62- className,
63- size,
64- } : ContributorAvatarProps ) => {
65- const intl = useIntl ( ) ;
66- const [ imgError , setImgError ] = useState ( false ) ;
67- return (
68- < Avatar
69- className = { className }
70- size = { size }
71- src = { imgError ? undefined : src }
72- alt = { username || intl . formatMessage ( messages . historyEntryDefaultUser ) }
73- onError = { ( ) => setImgError ( true ) }
74- />
75- ) ;
76- } ;
77-
7844const HistoryLogGroupTitle = ( {
7945 titleMessage,
8046 dateMessage,
@@ -105,64 +71,6 @@ const HistoryLogGroupTitle = ({
10571 ) ;
10672} ;
10773
108- const HistoryLogGroupEntries = ( {
109- entries,
110- } : HistoryLogGroupEntriesProps ) => {
111- const intl = useIntl ( ) ;
112-
113- const getEntryMessage = ( entry : LibraryHistoryEntry ) => {
114- switch ( entry . action ) {
115- case 'edited' :
116- return messages . historyEditEntry ;
117- case 'renamed' :
118- return messages . historyRenameEntry ;
119- case 'created' :
120- return messages . historyCreatedEntry ;
121- default :
122- return messages . historyEditEntry ;
123- }
124- } ;
125-
126- return (
127- < Stack gap = { 0 } >
128- < div className = "history-log-vert" />
129- { entries . map ( ( entry , index , arr ) => {
130- const isLast = index === arr . length - 1 ;
131- const entryMessage = getEntryMessage ( entry ) ;
132-
133- return (
134- < div key = { entry . changedAt } >
135- < Stack direction = "horizontal" gap = { 2 } className = "ml-1.5" >
136- < ContributorAvatar
137- username = { entry . contributor ?. username || intl . formatMessage ( messages . historyEntryDefaultUser ) }
138- src = { entry . contributor ?. profileImageUrls . medium }
139- className = "history-log-group-avatar small-avatar"
140- size = "sm"
141- />
142- < Stack >
143- < Stack direction = "horizontal" gap = { 1 } >
144- < FormattedMessage
145- { ...entryMessage }
146- values = { {
147- user : entry . contributor ?. username ?? intl . formatMessage ( messages . historyEntryDefaultUser ) ,
148- displayName : < span className = "history-log-title text-truncate" > { entry . title } </ span > ,
149- icon : < Icon src = { getItemIcon ( entry . itemType ) } /> ,
150- } }
151- />
152- </ Stack >
153- < span className = "small text-gray-500" >
154- { moment ( entry . changedAt ) . fromNow ( ) }
155- </ span >
156- </ Stack >
157- </ Stack >
158- { ! isLast && < div className = "history-log-vert" /> }
159- </ div >
160- ) ;
161- } ) }
162- </ Stack >
163- ) ;
164- } ;
165-
16674export const HistoryCreatedLogGroup = ( {
16775 user,
16876 displayName,
@@ -223,31 +131,6 @@ export const HistoryDraftLogGroup = ({
223131 ) ;
224132} ;
225133
226- const ContributorsAvatars = ( { contributors } : ContributorsAvatarsProps ) => {
227- const visible = contributors . slice ( 0 , MAX_VISIBLE_CONTRIBUTORS ) ;
228- return (
229- < Stack direction = "horizontal" gap = { 2 } className = "ml-4.5" >
230- < div className = "contributors-avatars" >
231- { visible . map ( ( { username, profileImageUrls } ) => (
232- < ContributorAvatar
233- key = { username }
234- size = "xs"
235- className = "contributors-avatar"
236- username = { username }
237- src = { profileImageUrls . small }
238- />
239- ) ) }
240- </ div >
241- < span className = "small" >
242- < FormattedMessage
243- { ...messages . historyContributors }
244- values = { { count : contributors . length } }
245- />
246- </ span >
247- </ Stack >
248- ) ;
249- } ;
250-
251134export const HistoryPublishLogGroup = ( {
252135 itemId,
253136 publishLogUuid,
0 commit comments