/** **************************************************************************** * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Licensed under the Apache License Version 2.0 (the 'License'). You may not * use this file except in compliance with the License. A copy of the License * is located at * * http://www.apache.org/licenses/ * or in the 'license' file accompanying this file. This file is distributed on * an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or * implied. See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************** */ /* eslint-disable no-underscore-dangle */ import React, { createRef } from 'react'; import PropTypes from 'prop-types'; import Dropzone from 'react-dropzone'; import { NorthStarThemeProvider } from 'aws-northstar'; import { withStyles } from '@material-ui/core/styles'; import Container from '@material-ui/core/Container'; import Grid from '@material-ui/core/Grid'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; import Tabs from '@material-ui/core/Tabs'; import Tab from '@material-ui/core/Tab'; import Box from '@material-ui/core/Box'; import Typography from '@material-ui/core/Typography'; import Link from '@material-ui/core/Link'; import DescriptionIcon from '@material-ui/icons/Description'; import FeedbackIcon from '@material-ui/icons/Feedback'; import './App.css'; import pkg from '../package.json'; import EmptyView from './EmptyView'; import DraggingView from './DraggingView'; import LoadingView from './LoadingView'; import SnapshotListView from './SnapshotListView'; import LogView from './LogView'; import SkewMetricsView from './SkewMetricsView'; import ApiCallMetricsView from './ApiCallMetricsView'; import RtcMetricsViewGroup from './RtcMetricsViewGroup'; import { buildIndex, findExtras, resetIndex, hasSoftphoneMetrics, resetSoftphoneMetrics, } from './utils/findExtras'; function TabPanel(props) { const { children, value, index, ...other } = props; return ( ); } TabPanel.propTypes = { children: PropTypes.node, index: PropTypes.any.isRequired, value: PropTypes.any.isRequired, }; TabPanel.defaultProps = { children: [], }; function a11yProps(index) { return { id: `simple-tab-${index}`, 'aria-controls': `simple-tabpanel-${index}`, }; } const styles = (theme) => ({ root: { flexGrow: 1, backgroundColor: '#f5f5f5', }, appbar: { backgroundColor: '#26303b', }, title: { flexGrow: 1, }, feedbackLink: { '& a': { display: 'inline-flex', verticalAlign: 'middle', justifyContent: 'center', alignItems: 'center', color: 'white', borderColor: 'white', fontSize: '13px', marginLeft: '13px', }, '& svg': { display: 'block', }, }, tab: { backgroundColor: '#2e3a48', }, content: { zIndex: 2, paddingTop: theme.spacing(2), paddingBottom: theme.spacing(2), }, leftIcon: { marginRight: theme.spacing(1), }, rightIcon: { marginLeft: theme.spacing(1), }, }); class App extends React.Component { constructor(props) { super(props); this.state = this.getInitialState(); this.selectLog = this.selectLog.bind(this); this.selectSnapshots = this.selectSnapshots.bind(this); this.handleChangeTab = this.handleChangeTab.bind(this); this.handleOnDrop = this.handleOnDrop.bind(this); this.handleExpandLogView = this.handleExpandLogView.bind(this); this.dropzoneRef = createRef(); if (window.File && window.FileReader && window.FileList && window.Blob) { // Great success! All the File APIs are supported. } else { // eslint-disable-next-line no-alert alert('The File APIs are not fully supported in this browser.'); } } getInitialState() { return { tabIndex: 0, isInitial: true, isLoading: false, isExpanded: false, filename: null, log: [], selectedLog: [], selectedSnapshots: [], indexedLogs: null, hasRtcLog: false, }; } handleOnDrop(files) { const allowedTypes = [ 'text/plain', 'application/json', ]; if (!allowedTypes.includes(files[0].type)) { // eslint-disable-next-line no-alert alert(`Error in processing ${files[0].name}: ${files[0].type} is not a supported file type.`); return; } const reader = new FileReader(); reader.onload = (e) => { try { resetIndex(); // rebuild the index for this file resetSoftphoneMetrics();// rebuild the SoftPhone metric for this file this.onLoadLog(JSON.parse(e.target.result)); } catch (error) { // eslint-disable-next-line no-alert alert(`I failed to load the file ${files[0].name}: ${error}`); } }; reader.onloadend = () => { this.setState({ isLoading: false }); }; this.setState({ isLoading: true, filename: files[0].name }); reader.readAsText(files[0]); } handleChangeTab(event, newValue) { this.setState({ tabIndex: newValue }); } handleExpandLogView() { this.setState((prevState) => ({ isExpanded: !prevState.isExpanded })); } onLoadLog(log) { const rearrangedLog = log .map((event, idx) => ( { ...event, _oriKey: idx, _ts: new Date(event.time).getTime() } )) .sort((a, b) => (a._ts === b._ts ? a._oriKey - b._oriKey : a._ts - b._ts)) .map((event, idx) => findExtras(event, idx)); const timeRange = [rearrangedLog[0]._ts, rearrangedLog[rearrangedLog.length - 1]._ts]; this.setState({ isInitial: false, // eslint-disable-next-line react/no-unused-state originalLog: log.map((event, idx) => ({ ...event, _oriKey: idx })), log: rearrangedLog, selectedLog: [], selectedSnapshots: [], indexedLogs: buildIndex(), hasRtcMetrics: hasSoftphoneMetrics(), timeRange, }); } selectLog(selectedLog) { this.setState({ selectedLog }); } selectSnapshots(selectedSnapshots) { this.setState({ selectedSnapshots }); } render() { const { tabIndex, isInitial, isLoading, isExpanded, filename, log, selectedLog, selectedSnapshots, indexedLogs, hasRtcMetrics, timeRange, } = this.state; const { classes } = this.props; return (
{({ getRootProps, isDragActive }) => ( // eslint-disable-next-line react/jsx-props-no-spreading
CCP Log Parser { filename && (  :  {filename} ) } e.preventDefault} > Version: {' '} {pkg.version} e.preventDefault} > User Guide e.preventDefault} > Send Feedback { (!isInitial && !isLoading) && ( {/* eslint-disable-next-line max-len */} {/* eslint-disable-next-line react/jsx-props-no-spreading */} {/* eslint-disable-next-line max-len */} {/* eslint-disable-next-line react/jsx-props-no-spreading */} ) } { isDragActive && } { (isInitial && !isLoading) && } { isLoading && } { (!isInitial && !isLoading) && ( <> { hasRtcMetrics && ( )} ) }
)}
); } } App.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles)(App);