Merge pull request #4566 from ethereum/TerminalUI

Terminal UI
pull/4551/head
bunsenstraat 8 months ago committed by GitHub
commit 30eae07bb9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      apps/remix-ide-e2e/src/commands/openFile.ts
  2. 2
      libs/remix-ui/panel/src/lib/plugins/panel.css
  3. 14
      libs/remix-ui/terminal/src/lib/components/remix-ui-terminal-bar.tsx
  4. 3
      libs/remix-ui/terminal/src/lib/components/remix-ui-terminal-menu-buttons.css
  5. 12
      libs/remix-ui/terminal/src/lib/components/remix-ui-terminal-menu-buttons.tsx
  6. 14
      libs/remix-ui/terminal/src/lib/components/remix-ui-terminal-menu.tsx
  7. 8
      libs/remix-ui/terminal/src/lib/remix-ui-terminal-wrapper.tsx
  8. 10
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
  9. 6
      libs/remix-ui/terminal/src/lib/types/terminalTypes.ts
  10. 44
      libs/remix-ui/xterm/src/lib/components/remix-ui-terminal-menu-xterm.tsx
  11. 2
      libs/remix-ui/xterm/src/lib/components/remix-ui-xterm.tsx
  12. 32
      libs/remix-ui/xterm/src/lib/components/remix-ui-xterminals.tsx
  13. 2
      libs/remix-ui/xterm/src/lib/components/xterm-wrap.tsx
  14. 72
      libs/remix-ui/xterm/src/lib/css/index.css

@ -21,7 +21,7 @@ function openFile (browser: NightwatchBrowser, name: string, done: VoidFunction)
// if side panel is shown, check this is the file panel
browser.element('css selector', '[data-id="verticalIconsKindfilePanel"] img[data-id="selected"]', (result) => {
if (result.status === 0) {
done()
done()
} else browser.clickLaunchIcon('filePanel').perform(() => {
done()
})

@ -104,7 +104,5 @@ iframe {
height: 2rem !important;
}
.terminal-wrap.minimized.desktop {
height: 4.5rem !important;
}

@ -22,16 +22,20 @@ export const RemixUITerminalBar = (props: RemixUiTerminalProps) => {
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">
<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"
>
<RemixUITerminalMenuToggle {...props} />
{platform === appPlatformTypes.desktop ?
<>
<div className='d-flex flex-row w-100 justify-content-between '>
<RemixUITerminalMenuButtons {...props} />
{xtermState.showOutput? <RemixUITerminalMenu {...props} />: <RemixUIXtermMenu {...props} />}
</> :
</div> :
<RemixUITerminalMenu {...props} />
}
</div>
</div></>)
</div></>
)
}

@ -1,6 +1,8 @@
import React, { useContext, useEffect } from 'react' // eslint-disable-line
import { TerminalContext } from '../context'
import { RemixUiTerminalProps, SET_OPEN } from '../types/terminalTypes'
import './remix-ui-terminal-menu-buttons.css'
export const RemixUITerminalMenuButtons = (props: RemixUiTerminalProps) => {
const { xtermState, dispatchXterm, terminalState, dispatch } = useContext(TerminalContext)
@ -17,9 +19,13 @@ export const RemixUITerminalMenuButtons = (props: RemixUiTerminalProps) => {
}
return (
<div>
<button className={`btn btn-sm btn-secondary mr-2 ${!xtermState.showOutput ? 'xterm-btn-none' : 'xterm-btn-active'}`} onClick={selectOutput}>output</button>
<button className={`btn btn-sm btn-secondary ${xtermState.terminalsEnabled ? '' : 'd-none'} ${xtermState.showOutput ? 'xterm-btn-none' : 'xterm-btn-active'}`} onClick={showTerminal}><span className="far fa-terminal border-0 ml-1"></span></button>
<div className='d-flex flex-row align-items-center'>
<button id="tabOutput" className={`xtermButton btn btn-sm border-secondary mr-2 border ${!xtermState.showOutput ? '' : 'd-flex btn-secondary'}`} onClick={selectOutput}>
Output
</button>
<button id="tabXTerm" className={`xtermButton btn btn-sm border-secondary ${xtermState.terminalsEnabled ? 'd-block' : 'd-none'} ${xtermState.showOutput ? 'd-none' : 'btn-secondary'}`} onClick={showTerminal}>
<span className="far fa-terminal border-0 ml-1"></span>
</button>
</div>
)
}

@ -26,12 +26,7 @@ export const RemixUITerminalMenu = (props: RemixUiTerminalProps) => {
dispatch({ type: 'search', payload: arg0 })
}
return (<>
<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>
return (<div className='d-flex flex-row align-items-center'>
<CustomTooltip placement="top" tooltipId="terminalClear" tooltipClasses="text-nowrap" tooltipText={<FormattedMessage id="terminal.pendingTransactions" />}>
<div className="mx-2">0</div>
</CustomTooltip>
@ -72,5 +67,10 @@ export const RemixUITerminalMenu = (props: RemixUiTerminalProps) => {
data-id="terminalInputSearch"
/>
</div>
</>)
<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>
</div>)
}

@ -23,10 +23,10 @@ export const RemixUITerminalWrapper = (props: RemixUiTerminalProps) => {
<RemixUITerminalBar {...props} />
{platform !== appPlatformTypes.desktop && <RemixUiTerminal {...props} />}
{platform === appPlatformTypes.desktop &&
<>
<RemixUiTerminal visible={xtermState.showOutput} plugin={props.plugin} onReady={props.onReady} />
<RemixUiXterminals {...props} />
</>
<>
<RemixUiTerminal visible={xtermState.showOutput} plugin={props.plugin} onReady={props.onReady} />
<RemixUiXterminals {...props} />
</>
}
</TerminalContext.Provider>
</>)

@ -556,11 +556,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
}))
}
const handleToggleTerminal = () => {
setIsOpen(!isOpen)
props.plugin.call('layout', 'minimize', props.plugin.profile.name, isOpen)
}
useEffect(() => {
;(async () => {
const storage = await props.plugin.call('storage', 'formatString', await props.plugin.call('storage', 'getStorage'))
@ -579,9 +574,8 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const classNameBlock = 'remix_ui_terminal_block px-4 py-1 text-break'
return (
( !props.visible? <></>:
<div style={{ flexGrow: 1 }} className="remix_ui_terminal_panel" ref={panelRef}>
( props.visible &&
<div style={{ flexGrow: 1 }} className="remix_ui_terminal_panel h-100" ref={panelRef}>
<div tabIndex={-1} className="remix_ui_terminal_container d-flex h-100 m-0 flex-column" data-id="terminalContainer">
{handleAutoComplete()}
<div className="position-relative d-flex flex-column-reverse h-100">

@ -31,7 +31,7 @@ export const SEARCH = 'search'
export const SET_ISVM = 'setIsVM'
export interface RemixUiTerminalProps {
plugin: any,
onReady: (api: any) => void,
visible: boolean,
plugin: any,
onReady: (api: any) => void,
visible: boolean,
}

@ -26,30 +26,34 @@ export const RemixUIXtermMenu = (props: RemixUiTerminalProps) => {
}
return (<>
<div className={`${xtermState.showOutput ? 'd-none' : ''}`}>
<button className="btn btn-sm btn-secondary mr-2" onClick={async () => onClearTerminal()}>
<CustomTooltip tooltipText={<FormattedMessage id='xterm.clear' defaultMessage='Clear terminal' />}>
<span className="far fa-ban border-0 p-0 m-0"></span>
</CustomTooltip>
</button>
<button className="btn btn-sm btn-secondary" onClick={async () => onCreateTerminal()}>
<div className={`d-flex flex-row align-items-center ${xtermState.showOutput ? 'd-none' : ''}`}>
<div className="mx-2" onClick={async () => onCreateTerminal()}>
<CustomTooltip tooltipText={<FormattedMessage id='xterm.new' defaultMessage='New terminal' />}>
<span className="far fa-plus border-0 p-0 m-0"></span>
<i className="fas fa-plus border-0 p-0 m-0"></i>
</CustomTooltip>
</div>
<div className=''>
<CustomTooltip tooltipText={<FormattedMessage id='xterm.shells' defaultMessage='Shells' />}>
<Dropdown as={ButtonGroup}>
<Dropdown.Toggle split variant="" id="dropdown-split-basic" />
<Dropdown.Menu className='custom-dropdown-items remixui_menuwidth'>
{xtermState.shells.map((shell, index) => {
return (<Dropdown.Item key={index} onClick={async () => await onCreateTerminal(shell)}>{shell}</Dropdown.Item>)
})}
</Dropdown.Menu>
</Dropdown>
</CustomTooltip>
</button>
<Dropdown as={ButtonGroup}>
<Dropdown.Toggle split variant="secondary" id="dropdown-split-basic" />
<Dropdown.Menu className='custom-dropdown-items remixui_menuwidth'>
{xtermState.shells.map((shell, index) => {
return (<Dropdown.Item key={index} onClick={async () => await onCreateTerminal(shell)}>{shell}</Dropdown.Item>)
})}
</Dropdown.Menu>
</Dropdown>
<button className="btn ml-2 btn-sm btn-secondary" onClick={onCloseTerminal}>
</div>
<div className="mx-2" onClick={onCloseTerminal}>
<CustomTooltip tooltipText={<FormattedMessage id='xterm.close' defaultMessage='Close terminal' />}>
<span className="far fa-trash border-0 ml-1"></span>
<i className="far fa-trash border-0 ml-1"></i>
</CustomTooltip>
</div>
<div className="mx-2" onClick={async () => onClearTerminal()}>
<CustomTooltip tooltipText={<FormattedMessage id='xterm.clear' defaultMessage='Clear Terminal' />}>
<i className="fas fa-ban border-0 p-0 m-0"></i>
</CustomTooltip>
</button>
</div>
</div>
</>)
}

@ -54,8 +54,6 @@ const RemixUiXterm = (props: RemixUiXtermProps) => {
resize(event, pid)
}
return (
<Xterm
addons={[fitAddon]}

@ -141,27 +141,39 @@ export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
}, [xtermState.showOutput])
return (<>
<div className='remix-ui-xterminals-container'>
{ <div style={{ flexGrow: 1 }} className={`flex-row ${xtermState.showOutput ? 'h-0 d-none' : 'h-100 d-flex'}`}>
<>
<div className={`remix-ui-xterminals-section ${xtermState.showOutput ? 'd-none' : 'd-flex'} `}>
{ <div className={`flex-row w-100 h-100 ${xtermState.showOutput ? 'h-0 d-none' : 'h-100 d-flex'}`}>
{terminals.map((xtermState) => {
return (
<div className={`h-100 xterm-terminal ${xtermState.hidden ? 'hide-xterm' : 'show-xterm'}`} key={xtermState.pid} data-id={`remixUIXT${xtermState.pid}`}>
<RemixUiXterm theme={theme} setTerminalRef={setTerminalRef} timeStamp={xtermState.timeStamp} send={send} resize={resize} pid={xtermState.pid} plugin={plugin}></RemixUiXterm>
<div className={`h-100 w-100 ${xtermState.hidden ? 'd-none' : 'd-block'}`} key={xtermState.pid} data-id={`remixUIXT${xtermState.pid}`}>
<RemixUiXterm
theme={theme}
setTerminalRef={setTerminalRef}
timeStamp={xtermState.timeStamp}
send={send}
resize={resize}
pid={xtermState.pid}
plugin={plugin}
></RemixUiXterm>
</div>
)
})}
<div className='remix-ui-xterminals-buttons border-left'>
<div className='d-flex flex-column border-left xterm-panel-left'>
{terminals.map((xtermState, index) => {
return (<button key={index} onClick={async () => selectTerminal(xtermState)} className={`btn btn-sm mt-2 btn-secondary ${xtermState.hidden ? 'xterm-btn-none' : 'xterm-btn-active'}`}><span className="fa fa-terminal border-0 p-0 m-0"></span></button>)
return (<button
key={index}
onClick={async () => selectTerminal(xtermState)}
className={`btn btn-sm m-1 p-1 px-2 ${xtermState.hidden ? 'border border-secondary' : 'btn-secondary'}`}
>
<span className="fa fa-terminal border-0 p-0 m-0"></span>
</button>)
})}
</div>
</div>
}
</>
</div>
</div>}
</>)
}

@ -232,6 +232,6 @@ export class Xterm extends React.Component<IProps> {
}
render() {
return <div className={this.props.className} ref={this.terminalRef} />
return <div className={`${this.props.className} mt-2 ml-2`} ref={this.terminalRef} />
}
}

@ -1,70 +1,4 @@
.remix-ui-xterminals-container {
display: flex;
flex-direction: row;
flex: 1;
}
.xterm-panel {
display: flex;
flex-direction: column;
flex: 1;
}
.remix-ui-xterminals-buttons {
display: flex;
flex-direction: column;
}
.hide-xterm{
display: none;
}
.show-xterm{
display: block;
}
.xterm-btn-active {
background-color: var(--primary);
}
.xterm-btn-none {
background-color: var(--secondary);
}
.xterm-terminal {
flex-grow: 1;
height: 100%;
width: 100%;
}
.xterm-panel-header-right {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-self: flex-end;
}
.xterm-panel-header {
display: flex;
flex-direction: row;
}
.xterm-panel-header-left {
display: flex;
flex-direction: row;
flex-grow: 1;
}
.remix-ui-xterminals-section {
display: flex;
flex-direction: row;
width: 100%;
z-index: 3;
}
.hide-terminals {
width: 0;
}
.show-terminals {
width: 100%;
.xterm-panel-left {
overflow-y: scroll;
margin-bottom: 2.1rem;
}

Loading…
Cancel
Save