blob: 3681399f5f256e1adfe853027207cc7cd2350a7f [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 Moment from 'moment';
import { Link } from 'react-router';
import CodeMirror from 'codemirror';
import 'codemirror/mode/sql/sql.js';
import 'codemirror/addon/runmode/runmode.js';
import UserStore from '../stores/UserStore';
import AdhocQueryActions from '../actions/AdhocQueryActions';
class QueryPreview extends React.Component {
constructor (props) {
super(props);
this.state = {showDetail: false};
this.toggleQueryDetails = this.toggleQueryDetails.bind(this);
this.cancelQuery = this.cancelQuery.bind(this);
}
render () {
let query = this.props;
if (!query.userQuery) return null;
// code below before the return prepares the data to render, turning out
// crude properties to glazed, garnished ones e.g. formatting of query
let codeTokens = [];
CodeMirror
.runMode(query.userQuery,
'text/x-mysql', function (text, style) {
// this method is called for every token and gives the
// token and style class for it.
codeTokens.push(<span className={'cm-' + style}>{text}</span>);
});
// figuring out the className for query status
// TODO optimize this construct
let statusTypes = {
'EXECUTED': 'success',
'SUCCESSFUL': 'success',
'FAILED': 'danger',
'CANCELED': 'danger',
'CLOSED': 'warning',
'QUEUED': 'info',
'RUNNING': 'info'
};
let statusClass = 'label-' + statusTypes[query.status.status] ||
'label-info';
let handle = query.queryHandle.handleId;
let executionTime = (query.finishTime - query.submissionTime) / (1000 * 60);
let statusType = query.status.status === 'ERROR' ? 'Error: ' : 'Status: ';
let seeResult = '';
let statusMessage = query.status.status === 'SUCCESSFUL' ?
query.status.statusMessage :
query.status.errorMessage;
if (query.status.status === 'SUCCESSFUL') {
seeResult = (<Link to='result' params={{handle: handle}}
className='btn btn-success btn-xs pull-right' style={{marginLeft: '5px'}}>
See Result
</Link>);
}
return (
<section>
<div className='panel panel-default'>
<pre className='cm-s-default' style={{cursor: 'pointer',
border: '0px', marginBottom: '0px'}}
onClick={this.toggleQueryDetails}>
{codeTokens}
<label className={'pull-right label ' + statusClass}>
{query.status.status}
</label>
{query.queryName && (
<label className='pull-right label label-primary'
style={{marginRight: '5px'}}>
{query.queryName}
</label>
)}
</pre>
{this.state.showDetail && (
<div className='panel-body' style={{borderTop: '1px solid #cccccc',
paddingBottom: '0px'}} key={'preview' + handle}>
<div className='row'>
<div className='col-lg-4 col-sm-4'>
<span className='text-muted'>Handle </span>
<strong>{ query.queryHandle.handleId || 'Unknown'}</strong>
</div>
<div className='col-lg-4 col-sm-4'>
<span className='text-muted'>Name </span>
<strong>{ query.queryName || 'Not specified'}</strong>
</div>
<div className='col-lg-4 col-sm-4'>
<span className='text-muted'>Submitted </span>
<strong>
{ Moment(query.submissionTime).format('Do MMM YY, hh:mm:ss a')}
</strong>
</div>
<div className='col-lg-4 col-sm-4'>
<span className='text-muted'>Execution time </span>
<strong>
{ executionTime > 0 ?
Math.ceil(executionTime) +
(executionTime > 1 ? ' mins' : ' min') : 'Still running'
}
</strong>
</div>
</div>
<div className='row'>
<div
className={'alert alert-' + statusTypes[query.status.status]}
style={{marginBottom: '0px', padding: '5px 15px 5px 15px'}}>
<p>
<strong>{statusType}</strong>
{statusMessage || query.status.status}
{seeResult}
<Link to='query' query={{handle: query.queryHandle.handleId}}
className='pull-right'>
Edit Query
</Link>
</p>
</div>
</div>
</div>
)}
</div>
</section>
);
}
toggleQueryDetails () {
this.setState({ showDetail: !this.state.showDetail });
}
cancelQuery () {
let secretToken = UserStore.getUserDetails().secretToken;
let handle = this.props && this.props.queryHandle &&
this.props.queryHandle.handleId;
if (!handle) return;
AdhocQueryActions.cancelQuery(secretToken, handle);
}
}
QueryPreview.propTypes = {
queryHandle: React.PropTypes.string
};
export default QueryPreview;