import * as React from 'react'; import Header from './Header'; import CodeViewer from './Viewer/CodeViewer'; import ScriptViewer from './Viewer/ScriptViewer'; import ScreenshotViewer from './Viewer/ScreenshotViewer'; import { BrowserProps, BrowserState } from './types'; import { withMeasurer } from 'src/components/modules/TestBox/withMeasurer'; import { connect } from 'react-redux'; import { setIsOpenForBrowser } from 'src/store/modules/app/actions'; import { bindActionCreators } from 'redux'; import { RootStore } from 'src/store/types/store'; import { browserSelector } from './selector'; import { TypeView } from 'src/store/modules/tests/types'; // TODO: вынести функциионал по аккордеону в отдельную компоненту class Browser extends React.Component { private screenshot: TypeView = 'screenshot'; private code: TypeView = 'code'; constructor(props) { super(props); const { result, result: { attempt }, } = this.props.data; this.state = { isOpen: true, viewData: result, viewType: this.screenshot, pageCount: attempt, pageCurrent: attempt, }; } public componentDidMount(): void { if (!this.isScreenShot()) { this.setState({ viewType: this.code }); } this.initStateFromCache(); this.setPageCount(); } public componentDidUpdate(prevProps): void { const { isRunning, measure } = this.props; if (prevProps.isRunning && !isRunning) { this.setPageCount(); } measure(); } public componentWillUnmount(): void { this.cacheState(); } public setPageCount = () => { const { result: { attempt, status }, } = this.props.data; let pageCount = attempt; if (attempt === 0 && status === 'idle') { pageCount = -1; } this.setState({ pageCount }); } private cacheState = () => { const { cache, suiteData } = this.props; const { isOpen, viewData, viewType, pageCurrent } = this.state; const suiteIndex = suiteData.suitePath.join(' '); cache.set(`browser-${viewData.name}`, suiteIndex, { isOpen, viewType, pageCurrent, }); } private initStateFromCache = () => { const { cache, suiteData, measure } = this.props; const { viewData } = this.state; const cacheTest = cache.data[suiteData.suitePath.join(' ')]; if (cacheTest) { const key = `browser-${viewData.name}`; if (cacheTest[key]) { this.setState( { isOpen: cacheTest[key].isOpen, viewType: cacheTest[key].viewType, pageCurrent: cacheTest[key].pageCurrent, }, measure, ); } } } private isScreenShot(): boolean { const { imagesInfo } = this.props.data.result; return imagesInfo.length > 0; } private handleViewChange = (viewType: TypeView): void => { this.setState({ viewType, isOpen: true }, this.props.measure); } private handleDataChange = (pageNumber: number): void => { const { measure, data: { result, retries } } = this.props; const { pageCount } = this.state; const resultPage = pageNumber === pageCount ? result : retries[pageNumber]; this.setState({ pageCurrent: pageNumber, isOpen: true, viewData: resultPage, }, measure); } private toggleBox = () => { this.setState( (prevState: BrowserState) => ({ isOpen: !prevState.isOpen }), this.props.measure, ); } private acceptBrowser = () => { const { viewData, pageCurrent } = this.state; this.props.onAccept(viewData.name, pageCurrent); } private renderViewer(): JSX.Element { let ViewerWrapper = null; const { viewType, viewData } = this.state; switch (viewType) { case 'code': ViewerWrapper = CodeViewer; break; case 'tests': ViewerWrapper = ScriptViewer; break; case 'screenshot': ViewerWrapper = ScreenshotViewer; break; } return ; } public render(): JSX.Element { const { isGui, url, status, gitUrl, skipComment } = this.props; const { viewType, pageCurrent, pageCount, viewData, isOpen } = this.state; return (
{isOpen && this.renderViewer()}
); } } // TODO: привести к нормальному виду const mapStateToProps = (store: RootStore, ownProps: BrowserProps) => ({ ...browserSelector(store, ownProps), }); const mapDispatchToProps = (dispatch) => ({ ...bindActionCreators({ setIsOpenForBrowser }, dispatch), }); export default connect( mapStateToProps, mapDispatchToProps, )(withMeasurer(Browser));