import TreeView from 'react-treeview';
import '../node_modules/react-treeview/react-treeview.css';
import AppHeader from 'widgets/header/header.jsx';
+import ScreenLoader from 'widgets/screen-loader/screenLoader.jsx';
var crashActions = require('./crashActions.js');
var crashStore = require('./crashStore.js');
// var MissionControlStore = require('../missioncontrol/missionControlStore.js');
function openDashboard() {
- window.location.hash = "#/";
+ window.location.hash = "#/";
}
class CrashDetails extends React.Component {
- constructor(props) {
- super(props)
- var self = this;
- this.state = crashStore.getState();
- crashStore.listen(this.storeListener);
- }
- storeListener = (data) => {
- this.setState({
- list:data.crashList,
- noDebug:!this.hasDebugData(data.crashList)
- });
- }
- componentWillUnmount(){
- crashStore.unlisten(this.storeListener);
- }
- componentWillMount() {
- crashStore.get();
- }
- hasDebugData(list) {
- console.log(list);
- if (list && list.length > 0) {
- for (let i = 0; i < list.length; i++) {
- var trace = list[i].backtrace;
- for (let j = 0; j < trace.length; j++) {
- console.log(trace[j])
- if (trace[j].detail) {
- return true;
- }
+ constructor(props) {
+ super(props)
+ this.state = crashStore.getState();
+ crashStore.listen(this.storeListener);
+ }
+ storeListener = (data) => {
+ this.setState({
+ isLoading: data.isLoading,
+ list: data.crashList,
+ noDebug: !this.hasDebugData(data.crashList)
+ });
+ }
+ componentWillUnmount() {
+ crashStore.unlisten(this.storeListener);
+ }
+ componentWillMount() {
+ crashStore.get();
+ }
+ hasDebugData(list) {
+ console.log(list);
+ if (list && list.length > 0) {
+ for (let i = 0; i < list.length; i++) {
+ var trace = list[i].backtrace;
+ for (let j = 0; j < trace.length; j++) {
+ console.log(trace[j])
+ if (trace[j].detail) {
+ return true;
+ }
+ }
+ }
}
- }
+ return false;
}
- return false;
- }
- downloadFile(fileName, urlData) {
- var replacedNewLines = urlData.replace(/\\n/g, '\n');
- var replacedTabs = replacedNewLines.replace(/\\t/g, '\t');
- var replacedQuotes= replacedTabs.replace(/\\"/g, '"');
- var textFileBlob = new Blob([replacedQuotes], {type: 'text/plain;charset=UTF-8'});
- var aLink = document.createElement('a');
- var evt = document.createEvent("HTMLEvents");
- evt.initEvent("click");
- aLink.download = fileName;
- aLink.href = window.URL.createObjectURL(textFileBlob);
- aLink.dispatchEvent(evt);
- }
- render() {
- let html;
- var list = null;
- if (this.state != null) {
- var tree = <div style={{'marginLeft':'auto', 'marginRight':'auto', 'width':'230px', 'padding':'90px'}}> No Debug Information Available </div>;
- if (!this.state.noDebug)
- {
- var tree = this.state.list && this.state.list.map((node, i) => {
- var vm = node.name;
- var vm_label = <span>{vm}</span>;
- var backtrace = node.backtrace;
- return (
- <TreeView key={vm + '|' + i} nodeLabel={vm_label} defaultCollapsed={false}>
- {backtrace.map(details => {
-
- //Needed to decode HTML
- var text_temp = document.createElement("textarea")
- text_temp.innerHTML = details.detail;
- var text_temp = text_temp.value;
- var arr = text_temp.split(/\n/);
- var text = [];
- for (let i = 0; i < arr.length; i++) {
- text.push(arr[i]);
- text.push(<br/>)
- }
+ downloadFile(fileName) {
+ // wait till download selected to create text blob
+ let urlData = JSON.stringify(this.state.list, null, 2);
+ let replacedNewLines = urlData.replace(/\\n/g, '\n');
+ let replacedTabs = replacedNewLines.replace(/\\t/g, '\t');
+ let replacedQuotes = replacedTabs.replace(/\\"/g, '"');
+ let textFileBlob = new Blob([replacedQuotes], { type: 'text/plain;charset=UTF-8' });
+ let aLink = document.createElement('a');
+ aLink.download = fileName;
+ aLink.href = window.URL.createObjectURL(textFileBlob);
+ aLink.click(); // suprise, this works without being on the page
+ // it seems to cause no problems cleaning up the blob right away
+ window.URL.revokeObjectURL(aLink.href);
+ // assuming aLink just goes away when this function ends
+ }
+ render() {
+ let html;
+ if (this.state != null) {
+ if (!this.state.noDebug) {
+ let tree = this.state.list && this.state.list.map((node, i) => {
+ const vm = node.name;
+ const vm_label = <span>{vm}</span>;
+ const backtrace = node.backtrace;
+ return (
+ <TreeView key={vm + '|' + i} nodeLabel={vm_label} defaultCollapsed={false}>
+ {backtrace.map(details => {
+ // do some trickery to normalize details 'new line' char(s)
+ let textareaElement = document.createElement("textarea")
+ textareaElement.innerHTML = details.detail;
+ let detailsFormatted = textareaElement.value;
+ let arr = detailsFormatted.split(/\n/);
+ let text = [];
+ for (let i = 0; i < arr.length; i++) {
+ text.push(arr[i]);
+ text.push(<br key={'line-' + i} />); // react likes keys on array children
+ }
- return (
- <TreeView nodeLabel={<span>{details.id}</span>} key={vm + '||' + details.id} defaultCollapsed={false}>
- <p>{text}</p>
- </TreeView>
- );
- })}
- </TreeView>
- );
- })}
- html = (
- <div className="crash-details-wrapper">
- <div className="form-actions">
- <button role="button" className="dark" onClick={this.state.noDebug ? false : this.downloadFile.bind(this, 'crash.txt', 'data:text;charset=UTF-8,' + decodeURIComponent(JSON.stringify(this.state.list, null, 2)))}> Download Crash Details</button>
- </div>
- <div className="crash-container">
- <h2> Debug Information </h2>
- <div className="tree">{tree}</div>
- </div>
- </div>
- );
- } else {
- html = <div className="crash-container"></div>
- };
- let refPage = window.sessionStorage.getItem('refPage');
- refPage = JSON.parse(refPage);
- return (
+ return (
+ <TreeView nodeLabel={<span>{details.id}</span>} key={vm + '||' + details.id} defaultCollapsed={false}>
+ <p>{text}</p>
+ </TreeView>
+ );
+ })}
+ </TreeView>
+ );
+ });
+ let doDownload = this.downloadFile.bind(this, 'crash.txt');
+ html = (
+ <div className="crash-details-wrapper">
+ <div className="form-actions">
+ <button role="button" className="dark" onClick={this.state.noDebug ? false : doDownload}>Download Crash Details</button>
+ </div>
+ <div className="crash-container">
+ <h2> Debug Information </h2>
+ <div className="tree">{tree}</div>
+ </div>
+ </div>
+ );
+ } else {
+ let text = this.state.isLoading ? "Loading Debug Information" : "No Debug Information Available"
+ html = (
+ <div className="crash-details-wrapper">
+ <div className="crash-container">
+ <div style={{ 'marginLeft': 'auto', 'marginRight': 'auto', 'width': '230px', 'padding': '90px' }}>{text}</div>
+ </div>
+ </div>
+ );
+ }
+ } else {
+ html = <div className="crash-container"></div>
+ };
+ let refPage = window.sessionStorage.getItem('refPage');
+ refPage = JSON.parse(refPage);
+ return (
<div className="crash-app">
- {html}
+ {html}
+ <ScreenLoader show={this.state.isLoading}/>
</div>
- );
- }
+ );
+ }
}
export default CrashDetails;