import React , { useEffect , useRef } from 'react' ; import styled from 'styled-components' ; import * as Icons from 'design/Icon' ; import { Box } from 'design' ; import { colors } from 'teleport/Console/colors' ; import useHttpTransfer from 'teleport/Console/FileTransfer/useHttpTransfer' ; import { File } from './../types' ; type FileListItemProps = { file : File ; onUpdate : ( partial : Partial < File > ) => void ; onRemove : ( id : number ) => void ; } ; export default function FileListItem ( props ) { const { file , onUpdate } = props ; const { name , id , isUpload , error , url , blob , status } = file ; const saved = useRef ( false ) ; const httpStatus = useHttpTransfer ( { blob , url , isUpload , } ) ; useEffect ( ( ) => { const { state , response } = httpStatus ; if ( state === 'completed' && ! isUpload ) { if ( ! saved . current ) { saved . current = true ; saveOnDisk ( response . fileName , response . blob ) ; } } onUpdate ( { id , status : httpStatus . state , error : httpStatus . error } ) ; } , [ httpStatus . state ] ) ; function onRemove ( ) { props . onRemove ( id ) ; } const completed = status === 'completed' ; const failed = status === 'error' ; const processing = status === 'processing' ; let statusText = `${ httpStatus . progress }%` ; if ( failed ) { statusText = 'failed' ; } else if ( completed ) { statusText = 'completed' ; } return ( < Box mt = "4px" > < Progress > < ProgressIndicator isCompleted = { completed } progress = { httpStatus . progress } > { name } < /ProgressIndicator> { processing && < CancelButton onClick = { onRemove } />} < ProgressStatus isFailed = { failed } > { statusText } < /ProgressStatus> < /Progress> { failed && < StyledError > { error } < /StyledError>} < /Box>); } const CancelButton = ( { onClick } ) => { return ( < StyledButton onClick = { onClick } > < Icons . Close /> < /StyledButton>); } ; function saveOnDisk ( fileName , blob ) { const a = document . createElement ( 'a' ) ; a . href = window . URL . createObjectURL ( blob ) ; a . download = fileName ; document . body . appendChild ( a ) ; a . click ( ) ; document . body . removeChild ( a ) ; } const StyledError = styled . div `
  line-height: 1.4;
  width: 360px;
  color: ${ colors . error };
` ; const Progress = styled . div `
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
` ; const ProgressStatus = styled . div `
  font-size: 12px;
  height: 24px;
  line-height: 24px;
  width: 80px;
  text-align: right;
  color: ${ props => ( props . isFailed ? colors . error : colors . terminal ) };
` ; const ProgressIndicator = styled . div `
  display: flex;
  align-items: center;
  word-break: break-word;
  background-image: linear-gradient(
    to right,
    ${ colors . terminalDark } 0%,
    ${ colors . terminalDark } ${ props => props . progress }%,
    ${ colors . bgTerminal } 0%,
    ${ colors . bgTerminal } 100%
  );

  background: ${ props => ( props . isCompleted ? 'none' : '' ) };
  color: ${ props => ( props . isCompleted ? colors . inverse : colors . terminal ) };

  min-height: 24px;
  line-height: 1.4;

  width: 360px;
` ; const StyledButton = styled . button `
  background: ${ colors . error };
  border-radius: 2px;
  border: none;
  color: ${ colors . light };
  cursor: pointer;
  font-size: 12px;
  height: 12px;
  outline: none;
  padding: 0;
  width: 12px;
  &:hover {
    background: ${ colors . error };
  }
` ;