import React, { Component } from 'react' import { Link } from 'react-router-dom' import Timestamp from './timestamp.js' import { api, httpGET, httpStreamGET } from '../http.js' import './output.css' let Convert = require('ansi-to-html') let converter = new Convert() export default class Output extends Component { constructor(props) { super(props) this.state = { job: null, xhr: null } } componentWillReceiveProps(props) { if (props.jobID && props.jobID !== this.props.jobID) { this.loadJob(props.jobID) } } componentDidMount() { this.loadJob(this.props.jobID) } componentWillUnmount() { if (this.state.xhr) { this.state.xhr.abort() } } loadJob(id) { if (id) { this.refs["output"].innerHTML = "" this.loadJobDetails(id) this.loadCommandLog(id) } } loadJobDetails(id) { httpGET(api("/jobs/" + id), (status, body) => { this.setState({ job: JSON.parse(body) }) }, (error) => { console.log("Failed to load job details:", error) } ) } loadCommandLog(id) { if (this.state.xhr) { this.state.xhr.abort() } let xhr = httpStreamGET(api("/jobs/" + id + "/log"), (chunk) => { // Progress let target = this.refs["output"] chunk = converter.toHtml(chunk) target.innerHTML += chunk.replace(/\n/g, "
") this.autoScroll() }, (status) => { // Complete // Request cancelled if (status === 0) { return } // Reload job details this.setState({ xhr: null }) this.loadJobDetails(id) }, (error) => { let target = this.refs["output"] target.innerHTML = "Failed to fetch command log: " + error } ) this.setState({ xhr: xhr }) } autoScroll() { // TODO: Figure out how to make it convinient } render() { let className = this.state.job ? "output visible" : "output" return (
{this.renderJobDetails()}
) } renderJobDetails() { let details = this.state.job if (!details) { return null } // let shortID = details.id.substring(0, 8) var state = details.state state = state.charAt(0).toUpperCase() + state.substr(1) var args if (details.args !== "") { args = {details.args} } return (
{details.command} {args} {details.flags}
ID
{details.id}
Status
{state}
User
{details.user.name}
{this.renderStarted()} {this.renderFinished()}
) } renderStarted() { let details = this.state.job return (
Started
) } renderFinished() { let details = this.state.job if (details.finished_at === null) { return null } return [
Finished
,
Took
] } }