import React from 'react' ; import { Typography , Box , Grid , Card , CardHeader , Divider , CardContent , makeStyles , Link , LinearProgress , Tooltip , } from '@material-ui/core' ; import { Entity } from '@backstage/catalog-model' ; import moment from 'moment' ; import { useLambda } from '../../hooks/useLambda' ; import { LambdaData } from '../../types' ; import { AWS_LAMBDA_ANNOTATION , AWS_LAMBDA_REGION_ANNOTATION , useServiceEntityAnnotations , } from '../../hooks/useServiceEntityAnnotations' ; import { MissingAnnotationEmptyState } from '@backstage/core-components' ; import ErrorBoundary from '../ErrorBoundary' ; import { useEntity } from "@backstage/plugin-catalog-react" ; type States = 'Pending' | 'Active' | 'Inactive' | 'Failed' ; const useStyles = makeStyles ( ( theme ) => ( { links : { margin : theme . spacing ( 2 , 0 ) , display : 'grid' , gridAutoFlow : 'column' , gridAutoColumns : 'min-content' , gridGap : theme . spacing ( 3 ) , } , label : { color : theme . palette . text . secondary , textTransform : 'uppercase' , fontSize : '10px' , fontWeight : 'bold' , letterSpacing : 0.5 , overflow : 'hidden' , whiteSpace : 'nowrap' , } , value : { fontWeight : 'bold' , overflow : 'hidden' , lineHeight : '24px' , wordBreak : 'break-word' , } , description : { wordBreak : 'break-word' , } , } ) ) ; const getElapsedTime = ( start ) => { return moment ( start ) . fromNow ( ) ; } ; const AboutField = ( { label , value , gridSizes , children , } ) => { const classes = useStyles ( ) ; const content = React . Children . count ( children ) ? ( children ) : ( < Typography variant = "body2" className = { classes . value } > { value || `unknown` } < /Typography>); return ( < Grid item { ... gridSizes } > < Typography variant = "subtitle2" className = { classes . label } > { label } < /Typography> { content } < /Grid>); } ; const State = ( { value } ) => { const colorMap = { Pending : '#dcbc21' , Active : 'green' , Inactive : 'black' , Failed : 'red' , } ; return ( < Box display = "flex" alignItems = "center" > < span style = { { display : 'block' , width : '8px' , height : '8px' , borderRadius : '50%' , backgroundColor : colorMap [ value ] , marginRight : '5px' , } } /> { value } < /Box>); } ; const OverviewComponent = ( { lambda } ) => { const href = `https://console.aws.amazon.com/lambda/home?region=${ lambda . region }#/functions/${ lambda . functionName }` ; const logsHref = `https://${ lambda . region }.console.aws.amazon.com/cloudwatch/home?region=${ lambda . region }#logStream:group=%252Faws%252Flambda%252F${ lambda . functionName }` ; const classes = useStyles ( ) ; return ( < Card > < CardHeader title = { < Typography variant = "h5" > AWS Lambda < /Typography>} subheader={<Typography variant="h6"> < Link target = "_blank" href = { href } > { lambda . functionName } < /Link> < /Typography>}/ > < Divider /> < CardContent > < Grid container > < AboutField label = "Description" gridSizes = { { xs : 12 } } > < Typography variant = "body2" paragraph className = { classes . description } > { lambda . description || 'No description' } < /Typography> < /AboutField> < AboutField label = "State" gridSizes = { { xs : 12 , sm : 6 , lg : 4 } } > < State value = { lambda . state as States } /> < /AboutField> < AboutField label = "Last modified" value = { getElapsedTime ( lambda . lastModifiedDate ! ) } gridSizes = { { xs : 12 , sm : 6 , lg : 4 } } /> < AboutField label = "Last update status" gridSizes = { { xs : 12 , sm : 6 , lg : 4 } } > < Tooltip disableHoverListener = { ! lambda . lastUpdateStatusReason } title = { lambda . lastUpdateStatusReason || '' } > < span > { lambda . lastUpdateStatus as string } < /span> < /Tooltip> < /AboutField> < AboutField label = "Logs" children = { < Link href = { logsHref } target = "_blank" > view logs < /Link>} gridSizes={{ xs: 12, sm: 6, lg: 4 }}/ > < /Grid> < /CardContent> < /Card>); } ; export const isRegionInAnnotations = ( entity ) => entity ?. metadata . annotations ?. [ AWS_LAMBDA_REGION_ANNOTATION ] ; export const isAWSLambdaAvailable = ( entity ) => entity ?. metadata . annotations ?. [ AWS_LAMBDA_ANNOTATION ] ; const AWSLambdaOverview = ( { entity } ) => { const { lambdaName , lambdaRegion } = useServiceEntityAnnotations ( entity ) ; const [ lambdaData ] = useLambda ( { lambdaName , region : lambdaRegion , } ) ; if ( lambdaData . loading ) { return ( < Card > < CardHeader title = { < Typography variant = "h5" > AWS Lambda < /Typography>}/ > < LinearProgress /> < /Card>); } return ( < > { lambdaData . lambda && < OverviewComponent lambda = { lambdaData . lambda } />}</ > ) ; } ; type Props = { deprecated entity ? : Entity ; } ; export const AWSLambdaOverviewWidget = ( _props ) => { const { entity } = useEntity ( ) ; return ! isRegionInAnnotations ( entity ) ? ( < MissingAnnotationEmptyState annotation = { AWS_LAMBDA_REGION_ANNOTATION } / > ) : ( < ErrorBoundary > < AWSLambdaOverview entity = { entity } / > < /ErrorBoundary>); } ;