import { Button , Classes , Tooltip } from '@blueprintjs/core' ; import _ from 'lodash' ; import { Component } from 'react' ; import { AutoSizer } from 'react-virtualized/dist/es/AutoSizer' ; import { CellMeasurer , CellMeasurerCache } from 'react-virtualized/dist/es/CellMeasurer' ; import { List , ListRowRenderer } from 'react-virtualized/dist/es/List' ; import HeadlessMessage from 'components/HeadlessMessage' ; import Notification from 'components/Notification' ; import { SerializedMessage } from 'libs/Message' ; import { SerializedNotification } from 'libs/Notification' ; import { isMessage , isNotification } from 'store/ducks/logs' ; import styled , { size , theme , ThemeProps , withTheme } from 'styled' ; /**
 * Wrapper component.
 */ const Wrapper = styled . div `
  background-color: ${ theme ( 'history.background' ) };
  border: 1px solid ${ theme ( 'history.border' ) };
  font-size: 0.82rem;
  height: ${ size ( 'history.height' ) };
  line-height: 1.4rem;
  margin-top: 20px;
  padding: 0;
  position: relative;
  width: 100%;
` ; /**
 * ButtonWrapper component.
 */ const ButtonWrapper = styled . div `
  position: absolute;
  right: 0;
  top: 0;
` ; /**
 * CopyButton component.
 */ const CopyButton = styled ( Button ) `
  &.${ Classes . BUTTON } {
    border-bottom-right-radius: 0;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }
` ; /**
 * History Component.
 */ class History extends Component < Props > { private logMeasureCache : CellMeasurerCache ; param props constructor ( props ) { super ( props ) ; this . logMeasureCache = new CellMeasurerCache ( { defaultHeight : props . theme . log . minHeight , fixedWidth : true , minHeight : props . theme . log . minHeight , } ) ; } return public render ( ) { const { logs } = this . props ; return ( < Wrapper > < AutoSizer onResize = { this . onResize } disableHeight > { ( { width } ) => ( < List deferredMeasurementCache = { this . logMeasureCache } height = { this . props . theme . history . height - 2 } rowHeight = { this . logMeasureCache . rowHeight } scrollToIndex = { logs . length - 1 } rowRenderer = { this . logRenderer } rowCount = { logs . length } overscanRowCount = { 10 } width = { width } / > ) } < /AutoSizer> < ButtonWrapper > < Tooltip content = "Copy all messages" > < CopyButton icon = "clipboard" onClick = { this . onClickCopyAllMessages } / > < /Tooltip> < /ButtonWrapper> < /Wrapper>); } private onResize = ( ) => { this . logMeasureCache . clearAll ( ) ; } ; private logRenderer : ListRowRenderer = ( { key , index , parent , style } ) => { const { logs } = this . props ; const log = logs [ index ] ; let LogComponent ; if ( isMessage ( log ) ) { LogComponent = < HeadlessMessage style = { style } onDoubleClick = { this . onDoubleClick } message = { log } / > ; } else if ( isNotification ( log ) ) { LogComponent = < Notification style = { style } notification = { log } / > ; } if ( _ . isNil ( LogComponent ) ) { return null ; } return ( < CellMeasurer cache = { this . logMeasureCache } columnIndex = { 0 } key = { key } parent = { parent } rowIndex = { index } > { LogComponent } < /CellMeasurer>); } ; private onDoubleClick = ( message ) => { const { copyMessageOnDoubleClick , copyMessageToClipboard } = this . props ; if ( copyMessageOnDoubleClick ) { copyMessageToClipboard ( message ) ; } } ; private onClickCopyAllMessages = ( ) => { const { copyMessageToClipboard , logs } = this . props ; const messages = _ . filter ( logs , isMessage ) ; copyMessageToClipboard ( messages ) ; } ; } export default withTheme ( History ) ; /**
 * React Props.
 */ interface Props extends ThemeProps { copyMessageOnDoubleClick : boolean ; copyMessageToClipboard : ( message : SerializedMessage | SerializedMessage [ ] ) => void ; logs : Array < SerializedMessage | SerializedNotification > ; }