pull/5370/head
filip mertens 9 months ago committed by bunsenstraat
parent 190b968e00
commit b1f4042469
  1. 35
      apps/remix-ide/src/app/panels/terminal.tsx
  2. 100
      libs/remix-ui/terminal/src/lib/components/remix-ui-terminal-bar.tsx
  3. 3
      libs/remix-ui/terminal/src/lib/context/context.ts
  4. 339
      libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts
  5. 21
      libs/remix-ui/terminal/src/lib/remix-ui-terminal-wrapper.tsx
  6. 72
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
  7. 1
      libs/remix-ui/terminal/src/lib/types/terminalTypes.ts

@ -1,6 +1,6 @@
/* global Node, requestAnimationFrame */ // eslint-disable-line /* global Node, requestAnimationFrame */ // eslint-disable-line
import React from 'react' // eslint-disable-line import React from 'react' // eslint-disable-line
import { RemixUiTerminal } from '@remix-ui/terminal' // eslint-disable-line import { RemixUiTerminal, RemixUITerminalWrapper } from '@remix-ui/terminal' // eslint-disable-line
import { Plugin } from '@remixproject/engine' import { Plugin } from '@remixproject/engine'
import * as packageJson from '../../../../../package.json' import * as packageJson from '../../../../../package.json'
import {Registry} from '@remix-project/remix-lib' import {Registry} from '@remix-project/remix-lib'
@ -26,6 +26,34 @@ const profile = {
} }
class Terminal extends Plugin { class Terminal extends Plugin {
fileImport: CompilerImports
event: any
globalRegistry: Registry
element: HTMLDivElement
eventsDecoder: any
txListener: any
_deps: { fileManager: any; editor: any; compilersArtefacts: any; offsetToLineColumnConverter: any }
commandHelp: { 'remix.loadgist(id)': string; 'remix.loadurl(url)': string; 'remix.execute(filepath)': string; 'remix.exeCurrent()': string; 'remix.help()': string }
blockchain: any
vm: typeof vm
_api: any
_opts: any
config: any
version: string
data: {
lineLength: any // ????
session: any[]; activeFilters: { commands: {}; input: string }; filterFns: {}
}
_view: { el: any; bar: any; input: any; term: any; journal: any; cli: any }
_components: {}
_commands: {}
commands: {}
_JOURNAL: any[]
_jobs: any[]
_INDEX: any
_shell: any
dispatch: any
terminalApi: any
constructor(opts, api) { constructor(opts, api) {
super(profile) super(profile)
this.fileImport = new CompilerImports() this.fileImport = new CompilerImports()
@ -114,9 +142,8 @@ class Terminal extends Plugin {
} }
updateComponent(state) { updateComponent(state) {
return (Registry.getInstance().get('platform').api.isDesktop()) ? <RemixUiXterminals onReady={state.onReady} plugin={state.plugin}> return (Registry.getInstance().get('platform').api.isDesktop()) ? <RemixUiXterminals onReady={state.onReady} plugin={state.plugin}/>
</RemixUiXterminals> : <RemixUITerminalWrapper
: <RemixUiTerminal
plugin={state.plugin} plugin={state.plugin}
onReady={state.onReady} onReady={state.onReady}
visible={true} visible={true}

@ -0,0 +1,100 @@
import { CustomTooltip } from '@remix-ui/helper'
import React, { useState, useEffect, useReducer, useRef, useContext } from 'react' // eslint-disable-line
import { FormattedMessage, useIntl } from 'react-intl'
import { TerminalContext } from '../context/context'
import { initialState, registerCommandReducer } from '../reducers/terminalReducer'
import { RemixUiTerminalProps } from '../types/terminalTypes'
export const RemixUITerminalBar = (props: RemixUiTerminalProps) => {
const { newstate: state, dispatch } = useContext(TerminalContext)
const [isVM, setIsVM] = useState(false)
const intl = useIntl()
const terminalMenu = useRef(null)
function handleToggleTerminal(event: any): void {
dispatch({ type: 'toggle' })
}
useEffect(() => {
props.plugin.call('layout', 'minimize', props.plugin.profile.name, !state.isOpen)
}, [state.isOpen])
useEffect(() => {
console.log('state change', state)
}, [state])
function handleClearConsole(event: any): void {
dispatch({ type: 'clearconsole', payload: [] })
}
function listenOnNetwork(event: any): void {
throw new Error('Function not implemented.')
}
function setSearchInput(arg0: string): void {
throw new Error('Function not implemented.')
}
return (<>
<div className="remix_ui_terminal_bar d-flex">
<div className="remix_ui_terminal_menu d-flex w-100 align-items-center position-relative border-top border-dark bg-light" ref={terminalMenu} data-id="terminalToggleMenu">
<CustomTooltip
placement="top"
tooltipId="terminalToggle"
tooltipClasses="text-nowrap"
tooltipText={state.isOpen ? <FormattedMessage id="terminal.hideTerminal" /> : <FormattedMessage id="terminal.showTerminal" />}
>
<i
className={`mx-2 remix_ui_terminal_toggleTerminal fas ${state.isOpen ? 'fa-angle-double-down' : 'fa-angle-double-up'}`}
data-id="terminalToggleIcon"
onClick={handleToggleTerminal}
></i>
</CustomTooltip>
<div className="mx-2 remix_ui_terminal_console" id="clearConsole" data-id="terminalClearConsole" onClick={handleClearConsole}>
<CustomTooltip placement="top" tooltipId="terminalClear" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="terminal.clearConsole" />}>
<i className="fas fa-ban" aria-hidden="true"></i>
</CustomTooltip>
</div>
<CustomTooltip placement="top" tooltipId="terminalClear" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="terminal.pendingTransactions" />}>
<div className="mx-2">0</div>
</CustomTooltip>
<CustomTooltip
placement="top"
tooltipId="terminalClear"
tooltipClasses="text-nowrap"
tooltipText={intl.formatMessage({ id: isVM ? 'terminal.listenVM' : 'terminal.listenTitle' })}
>
<div className="h-80 mx-3 align-items-center remix_ui_terminal_listenOnNetwork custom-control custom-checkbox">
<CustomTooltip placement="top" tooltipId="terminalClear" tooltipClasses="text-nowrap" tooltipText={intl.formatMessage({ id: 'terminal.listenTitle' })}>
<input
className="custom-control-input"
id="listenNetworkCheck"
onChange={listenOnNetwork}
type="checkbox"
disabled={isVM}
/>
</CustomTooltip>
<label
className="form-check-label custom-control-label text-nowrap"
style={{ paddingTop: '0.125rem' }}
htmlFor="listenNetworkCheck"
data-id="listenNetworkCheckInput"
>
<FormattedMessage id="terminal.listen" />
</label>
</div>
</CustomTooltip>
<div className="remix_ui_terminal_search d-flex align-items-center h-100">
<i className="remix_ui_terminal_searchIcon d-flex align-items-center justify-content-center fas fa-search bg-light" aria-hidden="true"></i>
<input
onChange={(event) => setSearchInput(event.target.value.trim())}
type="text"
className="remix_ui_terminal_filter border form-control"
id="searchInput"
placeholder={intl.formatMessage({ id: 'terminal.search' })}
data-id="terminalInputSearch"
/>
</div>
</div>
</div></>)
}

@ -0,0 +1,3 @@
import React from 'react'
export const TerminalContext = React.createContext(null)

@ -1,210 +1,213 @@
import { CLEAR_CONSOLE, CMD_HISTORY, EMPTY_BLOCK, ERROR, HTML, INFO, KNOWN_TRANSACTION, LISTEN_ON_NETWORK, LOG, TYPEWRITERLOG, TYPEWRITERWARNING, TYPEWRITERSUCCESS, NEW_TRANSACTION, SCRIPT, UNKNOWN_TRANSACTION, WARN } from '../types/terminalTypes' import {CLEAR_CONSOLE, CMD_HISTORY, EMPTY_BLOCK, ERROR, HTML, INFO, KNOWN_TRANSACTION, LISTEN_ON_NETWORK, LOG, TYPEWRITERLOG, TYPEWRITERWARNING, TYPEWRITERSUCCESS, NEW_TRANSACTION, SCRIPT, UNKNOWN_TRANSACTION, WARN, TOGGLE} from '../types/terminalTypes'
export const initialState = { export const initialState = {
journalBlocks: [ journalBlocks: [],
],
data: { data: {
// lineLength: props.options.lineLength || 80, // lineLength: props.options.lineLength || 80,
session: [], session: [],
activeFilters: { commands: {}, input: '' }, activeFilters: {commands: {}, input: ''},
filterFns: {} filterFns: {},
}, },
_commandHistory: [], _commandHistory: [],
_commands: {}, _commands: {},
commands: {}, commands: {},
_JOURNAL: [], _JOURNAL: [],
_jobs: [], _jobs: [],
_INDEX: { _INDEX: {},
},
_INDEXall: [], _INDEXall: [],
_INDEXallMain: [], _INDEXallMain: [],
_INDEXcommands: {}, _INDEXcommands: {},
_INDEXcommandsMain: {}, _INDEXcommandsMain: {},
message: [] message: [],
isOpen: true,
} }
export const registerCommandReducer = (state, action) => { export const registerCommandReducer = (state, action) => {
switch (action.type) { switch (action.type) {
case HTML : case HTML:
return { return {
...state, ...state,
_commands: Object.assign(initialState._commands, action.payload._commands), _commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands), commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, { ...action.payload.data }) data: Object.assign(initialState.data, {...action.payload.data}),
} }
case LOG: case LOG:
return { return {
...state, ...state,
_commands: Object.assign(initialState._commands, action.payload._commands), _commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands), commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, { ...action.payload.data }) data: Object.assign(initialState.data, {...action.payload.data}),
}
case INFO:
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data),
}
case WARN:
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data),
}
case ERROR:
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data),
}
case SCRIPT:
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data),
}
case CLEAR_CONSOLE:
console.log('clear console', state)
return {
...state,
...state.journalBlocks.splice(0),
}
} case TOGGLE:
case INFO: return {
return { ...state,
...state, isOpen: !state.isOpen,
_commands: Object.assign(initialState._commands, action.payload._commands), }
commands: Object.assign(initialState.commands, action.payload.commands), case LISTEN_ON_NETWORK:
data: Object.assign(initialState.data, action.payload.data) return {
} ...state,
case WARN: journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: 'text-log'}),
return { }
...state, default:
_commands: Object.assign(initialState._commands, action.payload._commands), return {state}
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data)
}
case ERROR:
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data)
}
case SCRIPT:
return {
...state,
_commands: Object.assign(initialState._commands, action.payload._commands),
commands: Object.assign(initialState.commands, action.payload.commands),
data: Object.assign(initialState.data, action.payload.data)
}
case CLEAR_CONSOLE:
return {
...state,
...state.journalBlocks.splice(0)
}
case LISTEN_ON_NETWORK:
return {
...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-log' })
}
default :
return { state }
} }
} }
export const registerFilterReducer = (state, action) => { export const registerFilterReducer = (state, action) => {
switch (action.type) { switch (action.type) {
case LOG: case LOG:
return { return {
...state, ...state,
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns),
}
} case INFO:
case INFO: return {
return { ...state,
...state, data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns),
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) }
} case WARN:
case WARN: return {
return { ...state,
...state, data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns),
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) }
} case ERROR:
case ERROR: return {
return { ...state,
...state, data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns),
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) }
} case SCRIPT:
case SCRIPT: return {
return { ...state,
...state, data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns),
data: Object.assign(initialState.data.filterFns, action.payload.data.filterFns) }
} default:
default : return {state}
return { state }
} }
} }
export const addCommandHistoryReducer = (state, action) => { export const addCommandHistoryReducer = (state, action) => {
switch (action.type) { switch (action.type) {
case CMD_HISTORY: case CMD_HISTORY:
return { return {
...state, ...state,
_commandHistory: initialState._commandHistory.unshift(action.payload.script) _commandHistory: initialState._commandHistory.unshift(action.payload.script),
}
} default:
default : return {state}
return { state }
} }
} }
export const remixWelcomeTextReducer = (state, action) => { export const remixWelcomeTextReducer = (state, action) => {
switch (action.type) { switch (action.type) {
case 'welcomeText' : case 'welcomeText':
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push(action.payload.welcomeText) journalBlocks: initialState.journalBlocks.push(action.payload.welcomeText),
} }
} }
} }
export const registerScriptRunnerReducer = (state, action) => { export const registerScriptRunnerReducer = (state, action) => {
switch (action.type) { switch (action.type) {
case HTML: case HTML:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-log', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: 'text-log', provider: action.payload.provider}),
} }
case LOG: case LOG:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-log', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: 'text-log', provider: action.payload.provider}),
} }
case TYPEWRITERLOG: case TYPEWRITERLOG:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, typewriter: true, style: 'text-log', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, typewriter: true, style: 'text-log', provider: action.payload.provider}),
} }
case TYPEWRITERWARNING: case TYPEWRITERWARNING:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, typewriter: true, style: 'text-warning', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, typewriter: true, style: 'text-warning', provider: action.payload.provider}),
} }
case TYPEWRITERSUCCESS: case TYPEWRITERSUCCESS:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, typewriter: true, style: 'text-success', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, typewriter: true, style: 'text-success', provider: action.payload.provider}),
} }
case INFO: case INFO:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-success', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: 'text-success', provider: action.payload.provider}),
} }
case WARN: case WARN:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-warning', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: 'text-warning', provider: action.payload.provider}),
} }
case ERROR: case ERROR:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-danger', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: 'text-danger', provider: action.payload.provider}),
} }
case SCRIPT: case SCRIPT:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: 'text-log', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: 'text-log', provider: action.payload.provider}),
} }
case KNOWN_TRANSACTION: case KNOWN_TRANSACTION:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '', name: 'knownTransaction', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: '', name: 'knownTransaction', provider: action.payload.provider}),
} }
case UNKNOWN_TRANSACTION: case UNKNOWN_TRANSACTION:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '', name: 'unknownTransaction', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: '', name: 'unknownTransaction', provider: action.payload.provider}),
} }
case EMPTY_BLOCK: case EMPTY_BLOCK:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '', name: 'emptyBlock', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: '', name: 'emptyBlock', provider: action.payload.provider}),
} }
case NEW_TRANSACTION: case NEW_TRANSACTION:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, style: '', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({message: action.payload.message, style: '', provider: action.payload.provider}),
} }
} }
} }

@ -1,7 +1,22 @@
import React, { useState, useEffect, useReducer, useRef} from 'react' // eslint-disable-line import React, { useReducer } from 'react' // eslint-disable-line
import { RemixUITerminalBar } from './components/remix-ui-terminal-bar'
import { TerminalContext } from './context/context'
import { initialState, registerCommandReducer } from './reducers/terminalReducer' import { initialState, registerCommandReducer } from './reducers/terminalReducer'
import RemixUiTerminal from './remix-ui-terminal'
import { RemixUiTerminalProps } from './types/terminalTypes'
export const RemixUITerminalWrapper = () => { export const RemixUITerminalWrapper = (props: RemixUiTerminalProps) => {
const [newstate, dispatch] = useReducer(registerCommandReducer, initialState) const [newstate, dispatch] = useReducer(registerCommandReducer, initialState)
return (<>terminal</>)
const providerState = {
newstate,
dispatch
}
return (<>
<TerminalContext.Provider value={providerState}>
<RemixUITerminalBar {...props} />
<RemixUiTerminal {...props} />
</TerminalContext.Provider>
</>)
} }

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useState, useEffect, useReducer, useRef, SyntheticEvent, MouseEvent } from 'react' // eslint-disable-line import React, { useState, useEffect, useReducer, useRef, SyntheticEvent, MouseEvent, useContext } from 'react' // eslint-disable-line
import { FormattedMessage, useIntl } from 'react-intl' import { FormattedMessage, useIntl } from 'react-intl'
import { import {
registerCommandAction, registerCommandAction,
@ -28,6 +28,7 @@ import RenderKnownTransactions from './components/RenderKnownTransactions' // es
import parse from 'html-react-parser' import parse from 'html-react-parser'
import { EMPTY_BLOCK, KNOWN_TRANSACTION, RemixUiTerminalProps, UNKNOWN_TRANSACTION } from './types/terminalTypes' import { EMPTY_BLOCK, KNOWN_TRANSACTION, RemixUiTerminalProps, UNKNOWN_TRANSACTION } from './types/terminalTypes'
import { wrapScript } from './utils/wrapScript' import { wrapScript } from './utils/wrapScript'
import { TerminalContext } from './context/context'
const _paq = (window._paq = window._paq || []) const _paq = (window._paq = window._paq || [])
/* eslint-disable-next-line */ /* eslint-disable-next-line */
@ -40,7 +41,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const [_cmdIndex, setCmdIndex] = useState(-1) const [_cmdIndex, setCmdIndex] = useState(-1)
const [_cmdTemp, setCmdTemp] = useState('') const [_cmdTemp, setCmdTemp] = useState('')
const [isOpen, setIsOpen] = useState<boolean>(true) const [isOpen, setIsOpen] = useState<boolean>(true)
const [newstate, dispatch] = useReducer(registerCommandReducer, initialState) const { newstate, dispatch } = useContext(TerminalContext)
const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState) const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState)
const [, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState) const [, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState)
const [toaster, setToaster] = useState(false) const [toaster, setToaster] = useState(false)
@ -155,8 +156,13 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
) )
}, [autoCompletState.text]) }, [autoCompletState.text])
useEffect(() => {
console.log('newstate.journalBlocks change', newstate.journalBlocks)
}, [newstate])
useEffect(() => { useEffect(() => {
scrollToBottom() scrollToBottom()
console.log('newstate.journalBlocks.length', newstate.journalBlocks)
}, [newstate.journalBlocks.length, toaster]) }, [newstate.journalBlocks.length, toaster])
function execute(file, cb) { function execute(file, cb) {
@ -586,67 +592,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
return ( return (
( !props.visible? <></>: ( !props.visible? <></>:
<div style={{ flexGrow: 1 }} className="remix_ui_terminal_panel" ref={panelRef}> <div style={{ flexGrow: 1 }} className="remix_ui_terminal_panel" ref={panelRef}>
<div className="remix_ui_terminal_bar d-flex">
<div className="remix_ui_terminal_menu d-flex w-100 align-items-center position-relative border-top border-dark bg-light" ref={terminalMenu} data-id="terminalToggleMenu">
<CustomTooltip
placement="top"
tooltipId="terminalToggle"
tooltipClasses="text-nowrap"
tooltipText={isOpen ? <FormattedMessage id="terminal.hideTerminal" /> : <FormattedMessage id="terminal.showTerminal" />}
>
<i
className={`mx-2 remix_ui_terminal_toggleTerminal fas ${isOpen ? 'fa-angle-double-down' : 'fa-angle-double-up'}`}
data-id="terminalToggleIcon"
onClick={handleToggleTerminal}
></i>
</CustomTooltip>
<div className="mx-2 remix_ui_terminal_console" id="clearConsole" data-id="terminalClearConsole" onClick={handleClearConsole}>
<CustomTooltip placement="top" tooltipId="terminalClear" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="terminal.clearConsole" />}>
<i className="fas fa-ban" aria-hidden="true"></i>
</CustomTooltip>
</div>
<CustomTooltip placement="top" tooltipId="terminalClear" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="terminal.pendingTransactions" />}>
<div className="mx-2">0</div>
</CustomTooltip>
<CustomTooltip
placement="top"
tooltipId="terminalClear"
tooltipClasses="text-nowrap"
tooltipText={intl.formatMessage({ id: isVM ? 'terminal.listenVM' : 'terminal.listenTitle'})}
>
<div className="h-80 mx-3 align-items-center remix_ui_terminal_listenOnNetwork custom-control custom-checkbox">
<CustomTooltip placement="top" tooltipId="terminalClear" tooltipClasses="text-nowrap" tooltipText={intl.formatMessage({ id: 'terminal.listenTitle' })}>
<input
className="custom-control-input"
id="listenNetworkCheck"
onChange={listenOnNetwork}
type="checkbox"
disabled={isVM}
/>
</CustomTooltip>
<label
className="form-check-label custom-control-label text-nowrap"
style={{ paddingTop: '0.125rem' }}
htmlFor="listenNetworkCheck"
data-id="listenNetworkCheckInput"
>
<FormattedMessage id="terminal.listen" />
</label>
</div>
</CustomTooltip>
<div className="remix_ui_terminal_search d-flex align-items-center h-100">
<i className="remix_ui_terminal_searchIcon d-flex align-items-center justify-content-center fas fa-search bg-light" aria-hidden="true"></i>
<input
onChange={(event) => setSearchInput(event.target.value.trim())}
type="text"
className="remix_ui_terminal_filter border form-control"
id="searchInput"
placeholder={intl.formatMessage({ id: 'terminal.search' })}
data-id="terminalInputSearch"
/>
</div>
</div>
</div>
<div tabIndex={-1} className="remix_ui_terminal_container d-flex h-100 m-0 flex-column" data-id="terminalContainer"> <div tabIndex={-1} className="remix_ui_terminal_container d-flex h-100 m-0 flex-column" data-id="terminalContainer">
{handleAutoComplete()} {handleAutoComplete()}
<div className="position-relative d-flex flex-column-reverse h-100"> <div className="position-relative d-flex flex-column-reverse h-100">

@ -23,6 +23,7 @@ export const WARN = 'warn'
export const ERROR = 'error' export const ERROR = 'error'
export const SCRIPT = 'script' export const SCRIPT = 'script'
export const CLEAR_CONSOLE = 'clearconsole' export const CLEAR_CONSOLE = 'clearconsole'
export const TOGGLE = 'toggle'
export const LISTEN_ON_NETWORK = 'listenOnNetWork' export const LISTEN_ON_NETWORK = 'listenOnNetWork'
export const CMD_HISTORY = 'cmdHistory' export const CMD_HISTORY = 'cmdHistory'

Loading…
Cancel
Save