import { useEffect , useCallback } from 'react' ; import convert from 'xml-js' ; import moment from 'moment' ; import { v4 as uuidv4 } from 'uuid' ; import { useApi } from '@backstage/core-plugin-api' ; import { useAsyncFn } from 'react-use' ; import { handleError } from './utils' ; import { ActivityStreamEntry , ActivityStreamElement , ActivityStreamKeys , } from '../types' ; import { jiraApiRef } from '../api' ; const getPropertyValue = ( entry , property ) : string => entry [ property ] ?. _text ; const getElapsedTime = ( start ) => moment ( start ) . fromNow ( ) ; const decodeHtml = ( html ) => { const txt = document . createElement ( 'textarea' ) ; txt . innerHTML = html ; return txt . value ; } ; export const useActivityStream = ( size , projectKey , isBearerAuth ) => { const api = useApi ( jiraApiRef ) ; const getActivityStream = useCallback ( async ( ) => { try { const response = await api . getActivityStream ( size , projectKey , isBearerAuth ) ; const parsedData = JSON . parse ( convert . xml2json ( response , { compact : true , spaces : 2 } ) ) ; const mappedData = parsedData . feed . entry . map ( ( entry ) : ActivityStreamElement => { const id = getPropertyValue ( entry , 'id' ) || `urn:uuid:${ uuidv4 ( ) }` ; const time = getPropertyValue ( entry , 'updated' ) ; const iconLink = entry . link ?. find ( link => link . _attributes . rel === 'http://streams.atlassian.com/syndication/icon' ) ; let icon ; if ( iconLink ) { icon = { url : iconLink . _attributes . href , title : iconLink . _attributes . title , } ; } return { id : id , time : { elapsed : getElapsedTime ( time ) , value : new Date ( time ) . toLocaleTimeString ( 'en-US' , { weekday : 'long' , year : 'numeric' , month : 'long' , day : 'numeric' , } ) , } , title : decodeHtml ( getPropertyValue ( entry , 'title' ) ) , icon : icon , summary : decodeHtml ( getPropertyValue ( entry , 'summary' ) || '' ) , content : decodeHtml ( getPropertyValue ( entry , 'content' ) || '' ) , } ; } ) ; return mappedData as Array < ActivityStreamElement > ; } catch ( err ) { return handleError ( err ) ; } } , [ api , size , projectKey , isBearerAuth ] ) ; const [ state , fetchActivityStream ] = useAsyncFn ( ( ) => getActivityStream ( ) , [ size , ] ) ; useEffect ( ( ) => { fetchActivityStream ( ) ; } , [ size , fetchActivityStream ] ) ; return { activitiesLoading : state . loading , activities : state . value , activitiesError : state . error , } ; } ;