blob: 6c659c3d70cde77ad6a79fae580ea6c2f9f28692 [file] [log] [blame]
/*
*
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import React from 'react';
import './crash.scss';
import TreeView from 'react-treeview';
import '../node_modules/react-treeview/react-treeview.css';
import AppHeader from 'widgets/header/header.jsx';
var crashActions = require('./crashActions.js');
var crashStore = require('./crashStore.js');
// var MissionControlStore = require('../missioncontrol/missionControlStore.js');
function openDashboard() {
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;
}
}
}
}
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/>)
}
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 (
<div className="crash-app">
{html}
</div>
);
}
}
export default CrashDetails;