4 * Copyright 2016 RIFT.IO Inc
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 import React from 'react';
20 import './crash.scss';
21 import TreeView from 'react-treeview';
22 import '../node_modules/react-treeview/react-treeview.css';
23 import AppHeader from 'widgets/header/header.jsx';
24 import ScreenLoader from 'widgets/screen-loader/screenLoader.jsx';
25 var crashActions = require('./crashActions.js');
26 var crashStore = require('./crashStore.js');
27 // var MissionControlStore = require('../missioncontrol/missionControlStore.js');
28 function openDashboard() {
29 window.location.hash = "#/";
31 class CrashDetails extends React.Component {
34 this.state = crashStore.getState();
35 crashStore.listen(this.storeListener);
37 storeListener = (data) => {
39 isLoading: data.isLoading,
41 noDebug: !this.hasDebugData(data.crashList)
44 componentWillUnmount() {
45 crashStore.unlisten(this.storeListener);
47 componentWillMount() {
52 if (list && list.length > 0) {
53 for (let i = 0; i < list.length; i++) {
54 var trace = list[i].backtrace;
55 for (let j = 0; j < trace.length; j++) {
57 if (trace[j].detail) {
65 downloadFile(fileName) {
66 // wait till download selected to create text blob
67 let urlData = JSON.stringify(this.state.list, null, 2);
68 let replacedNewLines = urlData.replace(/\\n/g, '\n');
69 let replacedTabs = replacedNewLines.replace(/\\t/g, '\t');
70 let replacedQuotes = replacedTabs.replace(/\\"/g, '"');
71 let textFileBlob = new Blob([replacedQuotes], { type: 'text/plain;charset=UTF-8' });
72 let aLink = document.createElement('a');
73 aLink.download = fileName;
74 aLink.href = window.URL.createObjectURL(textFileBlob);
75 aLink.click(); // suprise, this works without being on the page
76 // it seems to cause no problems cleaning up the blob right away
77 window.URL.revokeObjectURL(aLink.href);
78 // assuming aLink just goes away when this function ends
82 if (this.state != null) {
83 if (!this.state.noDebug) {
84 let tree = this.state.list && this.state.list.map((node, i) => {
86 const vm_label = <span>{vm}</span>;
87 const backtrace = node.backtrace;
89 <TreeView key={vm + '|' + i} nodeLabel={vm_label} defaultCollapsed={false}>
90 {backtrace.map(details => {
91 // do some trickery to normalize details 'new line' char(s)
92 let textareaElement = document.createElement("textarea")
93 textareaElement.innerHTML = details.detail;
94 let detailsFormatted = textareaElement.value;
95 let arr = detailsFormatted.split(/\n/);
97 for (let i = 0; i < arr.length; i++) {
99 text.push(<br key={'line-' + i} />); // react likes keys on array children
103 <TreeView nodeLabel={<span>{details.id}</span>} key={vm + '||' + details.id} defaultCollapsed={false}>
111 let doDownload = this.downloadFile.bind(this, 'crash.txt');
113 <div className="crash-details-wrapper">
114 <div className="form-actions">
115 <button role="button" className="dark" onClick={this.state.noDebug ? false : doDownload}>Download Crash Details</button>
117 <div className="crash-container">
118 <h2> Debug Information </h2>
119 <div className="tree">{tree}</div>
124 let text = this.state.isLoading ? "Loading Debug Information" : "No Debug Information Available"
126 <div className="crash-details-wrapper">
127 <div className="crash-container">
128 <div style={{ 'marginLeft': 'auto', 'marginRight': 'auto', 'width': '230px', 'padding': '90px' }}>{text}</div>
134 html = <div className="crash-container"></div>
136 let refPage = window.sessionStorage.getItem('refPage');
137 refPage = JSON.parse(refPage);
139 <div className="crash-app">
141 <ScreenLoader show={this.state.isLoading}/>
146 export default CrashDetails;