Skip to content

Commit 21e5390

Browse files
committed
[dashboard] Refactor WorkspaceLogs to React Hooks
1 parent f136149 commit 21e5390

File tree

1 file changed

+33
-48
lines changed

1 file changed

+33
-48
lines changed

components/dashboard/src/components/WorkspaceLogs.tsx

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,24 @@
55
*/
66

77
import EventEmitter from 'events';
8-
import React from 'react';
8+
import { useEffect, useRef } from 'react';
99
import { Terminal, ITerminalOptions, ITheme } from 'xterm';
1010
import { FitAddon } from 'xterm-addon-fit'
1111
import 'xterm/css/xterm.css';
12-
import { DisposableCollection } from '@gitpod/gitpod-protocol';
1312

1413
export interface WorkspaceLogsProps {
1514
logsEmitter: EventEmitter;
1615
errorMessage?: string;
1716
classes?: string;
1817
}
1918

20-
export interface WorkspaceLogsState {
21-
}
22-
23-
export default class WorkspaceLogs extends React.Component<WorkspaceLogsProps, WorkspaceLogsState> {
24-
protected xTermParentRef: React.RefObject<HTMLDivElement>;
25-
protected terminal: Terminal | undefined;
26-
protected fitAddon: FitAddon | undefined;
27-
28-
constructor(props: WorkspaceLogsProps) {
29-
super(props);
30-
this.xTermParentRef = React.createRef();
31-
}
19+
export default function WorkspaceLogs(props: WorkspaceLogsProps) {
20+
const xTermParentRef = useRef<HTMLDivElement>(null);
21+
const terminalRef = useRef<Terminal>();
22+
const fitAddon = new FitAddon();
3223

33-
private readonly toDispose = new DisposableCollection();
34-
componentDidMount() {
35-
const element = this.xTermParentRef.current;
36-
if (element === null) {
24+
useEffect(() => {
25+
if (!xTermParentRef.current) {
3726
return;
3827
}
3928
const theme: ITheme = {};
@@ -44,46 +33,42 @@ export default class WorkspaceLogs extends React.Component<WorkspaceLogsProps, W
4433
theme,
4534
scrollback: 9999999,
4635
};
47-
this.terminal = new Terminal(options);
48-
this.fitAddon = new FitAddon();
49-
this.terminal.loadAddon(this.fitAddon);
50-
this.terminal.open(element);
51-
this.props.logsEmitter.on('logs', logs => {
52-
if (this.fitAddon && this.terminal && logs) {
53-
this.terminal.write(logs);
36+
const terminal = new Terminal(options);
37+
terminalRef.current = terminal;
38+
terminal.loadAddon(fitAddon);
39+
terminal.open(xTermParentRef.current);
40+
props.logsEmitter.on('logs', logs => {
41+
if (fitAddon && terminal && logs) {
42+
terminal.write(logs);
5443
}
5544
});
56-
this.toDispose.push(this.terminal);
57-
this.fitAddon.fit();
45+
fitAddon.fit();
46+
return function cleanUp() {
47+
terminal.dispose();
48+
}
49+
});
5850

51+
useEffect(() => {
5952
// Fit terminal on window resize (debounced)
6053
let timeout: NodeJS.Timeout | undefined;
6154
const onWindowResize = () => {
6255
clearTimeout(timeout!);
63-
timeout = setTimeout(() => this.fitAddon!.fit(), 20);
56+
timeout = setTimeout(() => fitAddon!.fit(), 20);
6457
};
6558
window.addEventListener('resize', onWindowResize);
66-
this.toDispose.push({
67-
dispose: () => {
68-
clearTimeout(timeout!);
69-
window.removeEventListener('resize', onWindowResize);
70-
}
71-
});
72-
}
73-
74-
componentDidUpdate() {
75-
if (this.terminal && this.props.errorMessage) {
76-
this.terminal.write(`\n\u001b[38;5;196m${this.props.errorMessage}\u001b[0m`);
59+
return function cleanUp() {
60+
clearTimeout(timeout!);
61+
window.removeEventListener('resize', onWindowResize);
7762
}
78-
}
63+
});
7964

80-
componentWillUnmount() {
81-
this.toDispose.dispose();
82-
}
65+
useEffect(() => {
66+
if (terminalRef.current && props.errorMessage) {
67+
terminalRef.current.write(`\n\u001b[38;5;196m${props.errorMessage}\u001b[0m`);
68+
}
69+
}, [ terminalRef.current, props.errorMessage ]);
8370

84-
render() {
85-
return <div className={`mt-6 ${this.props.classes || 'h-72 w-11/12 lg:w-3/5'} rounded-xl bg-black relative`}>
86-
<div className="absolute top-0 left-0 bottom-0 right-0 m-6" ref={this.xTermParentRef}></div>
87-
</div>;
88-
}
71+
return <div className={`mt-6 ${props.classes || 'h-72 w-11/12 lg:w-3/5'} rounded-xl bg-black relative`}>
72+
<div className="absolute top-0 left-0 bottom-0 right-0 m-6" ref={xTermParentRef}></div>
73+
</div>;
8974
}

0 commit comments

Comments
 (0)