/** * Copyright 2018-present Facebook. * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * @format */ import {Component} from 'react'; import { CodeBlock, colors, ManagedTable, FlexColumn, Text, ManagedDataInspector, Input, View, } from '../index'; import styled from '../styled/index'; import type {TableBodyRow, TableRows} from 'sonar'; import type {PluginClient} from '../../plugin'; type ValueWithType = {| type: string, value: any, |}; type SuccessResult = {| isSuccess: true, value: ValueWithType, |}; type FailedResult = {| isSuccess: false, error: string, |}; type CommandResult = SuccessResult | FailedResult; type Props = { client: PluginClient, getContext: () => string, }; type State = { isConsoleEnabled: boolean, script: string, previousExecutions: Array<{ command: string, result: CommandResult, }>, }; class ConsoleError extends Component<{ error: Error | string | void, className?: string, }> { static Container = styled(CodeBlock)({ backgroundColor: colors.redTint, color: colors.red, overflow: 'auto', flexGrow: 1, margin: '0 -8px', padding: '0 8px', }); render() { const {className, error} = this.props; return ( {error} ); } } export class Console extends Component { static title = 'Console'; static id = 'Console'; static icon = 'chevron-right'; static TableColumns = { command: { value: 'Commands', }, }; static Window = styled(FlexColumn)({ padding: '15px', flexGrow: 1, }); static Input = styled(Input)({ width: '100%', }); constructor(props: Props) { super(props); this.state = { isConsoleEnabled: false, script: '', previousExecutions: [], }; } executeScriptOnDevice = () => { this.props.client .call('executeCommand', { command: this.state.script, context: this.props.getContext(), }) .then((result: ValueWithType) => { this.setState({ script: '', previousExecutions: [ ...this.state.previousExecutions, { command: this.state.script, result: {isSuccess: true, value: result}, }, ], }); }) .catch((onReject?) => { this.setState({ previousExecutions: [ ...this.state.previousExecutions, { command: this.state.script, result: { isSuccess: false, error: (onReject && onReject.message) || '', }, }, ], }); }); }; onInputChange = (event: SyntheticInputEvent<>) => { this.setState({script: event.target.value}); }; onSubmit = (event: SyntheticEvent<>) => { if (this.state.script != '') { this.executeScriptOnDevice(); } event.preventDefault(); }; buildCommandResultRowPair( command: string, result: CommandResult, index: number, ): TableRows { const key = index * 2; const commandRow: TableBodyRow = { columns: { command: {value: {command}}, }, key: key.toString(), }; const resultRow: TableBodyRow = { columns: { command: { value: result.isSuccess ? ( ) : ( ), }, }, key: (key + 1).toString(), }; return [commandRow, resultRow]; } renderPreviousCommands() { const rows: TableRows = this.state.previousExecutions .map(({command, result}, index) => this.buildCommandResultRowPair(command, result, index), ) .reduce((x, y) => x.concat(y), []); return rows.length ? ( ) : null; } render() { return ( {this.renderPreviousCommands()}
); } }