import { Entity } from '@backstage/catalog-model' ; import { InfoCard , ErrorBoundary , MissingAnnotationEmptyState , Table , TableColumn , } from '@backstage/core-components' ; import { configApiRef , useApi } from '@backstage/core-plugin-api' ; import { useEntity } from '@backstage/plugin-catalog-react' ; import { LinearProgress , Tooltip , Link } from '@material-ui/core' ; import React from 'react' ; import { isArgocdAvailable } from '../Router' ; import { ArgoCDAppDetails , ArgoCDAppList } from '../types' ; import { useAppDetails } from './useAppDetails' ; import { ARGOCD_ANNOTATION_APP_NAME , useArgoCDAppData , } from './useArgoCDAppData' ; import SyncIcon from '@material-ui/icons/Sync' ; import moment from 'moment' ; const HistoryTable = ( { data , retry , } ) => { const configApi = useApi ( configApiRef ) ; const baseUrl = configApi . getOptionalString ( 'argocd.baseUrl' ) ; const history = data . items ? data . items . map ( app => { if ( typeof app . status . history !== 'undefined' ) { return app . status . history . map ( entry => { return { app : app . metadata . name , instance : app . metadata ?. instance ?. name , ... entry , } ; } ) ; } return { } ; } ) . filter ( value => Object . keys ( value ) . length !== 0 ) . flat ( ) : [ ] ; const columns = [ { title : 'Name' , field : 'name' , render : ( row ) : React . ReactNode => baseUrl ? ( < Link href = { `${ baseUrl }/applications/${ row . app }` } target = "_blank" rel = "noopener" > { row . app } < /Link>) : (row.app), highlight : true , } , { title : 'Instance' , render : ( row ) : React . ReactNode => row . instance , } , { title : 'Deploy Started' , field : 'deployStartedAt' , render : ( row ) => ( < Tooltip title = { row . deployStartedAt ? row . deployStartedAt : 'Deploy started at' } placement = "left" > < div > { row . deployStartedAt ? moment ( row . deployStartedAt ) . fromNow ( ) : '-' } < /div> < /Tooltip>), } , { title : 'Deployed At' , field : 'deployedAt' , render : ( row ) => ( < Tooltip title = { row . deployedAt } placement = "left" > < div > { moment ( row . deployedAt ) . fromNow ( ) } < /div> < /Tooltip>), } , { title : 'Deploy duration' , render : ( row ) : React . ReactNode => moment . duration ( moment ( row . deployStartedAt ) . diff ( moment ( row . deployedAt ) ) ) . humanize ( ) , sorting : false , } , { title : 'Revision' , field : 'revision' , sorting : false , } , ] ; return ( < Table title = "ArgoCD history" options = { { paging : false , search : false , draggable : false , padding : 'dense' , } } data = { history } columns = { columns } actions = { [ { icon : ( ) => < SyncIcon />, tooltip : 'Refresh' , isFreeAction : true , onClick : ( ) => retry ( ) , } , ] } / > ) ; } ; const ArgoCDHistory = ( { entity } ) => { const { url , appName , appSelector , projectName } = useArgoCDAppData ( { entity , } ) ; const { loading , value , error , retry } = useAppDetails ( { url , appName , appSelector , projectName , } ) ; if ( loading ) { return ( < InfoCard title = "ArgoCD history" > < LinearProgress /> < /InfoCard>); } if ( error ) { return ( < InfoCard title = "ArgoCD history" > Error occurred while fetching data . { error . message } < /InfoCard>); } if ( value ) { if ( ( value as ArgoCDAppList ) . items !== undefined ) { return ( < HistoryTable data = { value as ArgoCDAppList } retry = { retry } / > ) ; } if ( Array . isArray ( value ) ) { const wrapped = { items : value as Array < ArgoCDAppDetails > , } ; return ( < HistoryTable data = { wrapped } retry = { retry } / > ) ; } const wrapped = { items : [ value as ArgoCDAppDetails ] , } ; return < HistoryTable data = { wrapped } retry = { retry } / > ; } return null ; } ; export const ArgoCDHistoryCard = ( ) => { const { entity } = useEntity ( ) ; return ! isArgocdAvailable ( entity ) ? ( < MissingAnnotationEmptyState annotation = { ARGOCD_ANNOTATION_APP_NAME } / > ) : ( < ErrorBoundary > < ArgoCDHistory entity = { entity } / > < /ErrorBoundary>); } ;