import * as React from 'react' ; import { IProgressProps , IProgressAction , ProgressActionState , IProgressState } from './IProgress' ; import { Action } from './Action' ; import { ProgressIndicator } from 'office-ui-fabric-react/lib/ProgressIndicator' ; import styles from './Progress.module.scss' ; import * as telemetry from "../../common/telemetry" ; /**
* Component to show progress of multiple SEQUENTIALLY executed actions
*/ export class Progress extends React . Component < IProgressProps , IProgressState > { constructor ( props ) { super ( props ) ; telemetry . track ( 'ReactProgress' , { } ) ; this . state = { showLongRunningText : props . longRunningText && ! props . longRunningTextDisplayDelay } ; } /**
     * componentDidUpdate lifecycle hook
     */ public componentDidUpdate ( ) { if ( this . props . longRunningText && this . props . longRunningTextDisplayDelay && this . props . currentActionIndex === 0 ) { setTimeout ( ( ) => { this . setState ( { showLongRunningText : true } ) ; } , this . props . longRunningTextDisplayDelay ) ; } if ( this . state . showLongRunningText && this . props . currentActionIndex >= this . props . actions . length ) { this . setState ( { showLongRunningText : false } ) ; } } param nextProps public shouldComponentUpdate ( nextProps ) { if ( this . props . currentActionIndex !== nextProps . currentActionIndex || this . props . showOverallProgress !== nextProps . showOverallProgress || this . props . title !== nextProps . title || ! this . _areActionsEqual ( this . props . actions , nextProps . actions ) ) { return true ; } } /**
     * Default React render method
     */ public render ( ) { const { currentActionIndex , showOverallProgress , showIndeterminateOverallProgress , hideNotStartedActions , title , actions , height , longRunningText , className , headerClassName , actionClassName , actionsContainerClassName , successIconName , errorIconName , inProgressIconName } = this . props ; let actionIndex = currentActionIndex ; if ( actionIndex > actions . length ) { actionIndex = actions . length ; } const actionsToRender = hideNotStartedActions ? actions . filter ( ( a , index ) => { return index <= currentActionIndex ; } ) : actions ; const actionEls = actionsToRender . map ( ( a , index ) => { let state = ProgressActionState . notStarted ; if ( a . hasError && index <= actionIndex ) { state = ProgressActionState . errored ; } else if ( actionIndex === index ) { state = ProgressActionState . inProgress ; } else if ( index < actionIndex ) { state = ProgressActionState . finished ; } return < Action { ... a } state = { state } key = { index } className = { actionClassName } successIconName = { successIconName } errorIconName = { errorIconName } inProgressIconName = { inProgressIconName } / > ; } ) ; let progress = 0 ; let progressSubTtext = '' ; if ( showIndeterminateOverallProgress ) { if ( actionIndex || actionIndex < actions . length ) { progress = null ; progressSubTtext = `${ ( actionIndex / actions . length * 100 ) . toFixed ( 0 ) }%` ; } } else { progress = actionIndex ? actionIndex / actions . length : 0 ; progressSubTtext = actionIndex ? `${ ( progress * 100 ) . toFixed ( 0 ) }%` : '' ; } return ( < div className = { `${ styles . progress } ${ className || "" }` } style = { { height : height || 'auto' } } > { ( title || showOverallProgress || this . state . showLongRunningText ) && ( < div className = { `${ styles . header } ${ headerClassName || "" }` } > < div className = { styles . title } > { title } < /div> { showOverallProgress && ( < div className = { styles . progressIndicator } > < ProgressIndicator percentComplete = { progress } /> < /div>)} { ( showOverallProgress && progressSubTtext ) && < span className = { styles . progressSubtext } > { progressSubTtext } < /span>} { this . state . showLongRunningText && < div className = { styles . longRunningText } > { longRunningText } < /div>} < /div>)} < div className = { `${ styles . actionsContainer } ${ actionsContainerClassName || "" }` } > { actionEls } < /div> < /div>); } private _areActionsEqual ( actions , nextActions ) { if ( actions . length !== nextActions . length ) { return false ; } for ( let i = 0 , len = actions . length ; i < len ; i ++ ) { const action = actions [ i ] ; const nextAction = nextActions [ i ] ; if ( action . hasError !== nextAction . hasError ) { return false ; } } return true ; } }