Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit ba84805

Browse files
committed
fix(plugins/plugin-client-common): when proxy disconnects, all terminal state is lost
part of #8030
1 parent 2e07307 commit ba84805

File tree

6 files changed

+67
-37
lines changed

6 files changed

+67
-37
lines changed

plugins/plugin-client-common/src/components/Client/Kui.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export class Kui extends React.PureComponent<Props, State> {
188188
return (
189189
<Alert
190190
hideCloseButton
191-
className="kui--terminal-alert kui--connection-lost"
191+
className="kui--terminal-alert kui--connection-lost top-pad left-pad right-pad"
192192
alert={{
193193
type: 'error',
194194
title: strings('Lost connection to your cluster'),
@@ -217,7 +217,10 @@ export class Kui extends React.PureComponent<Props, State> {
217217

218218
private defaultLoadingError() {
219219
return err => (
220-
<Alert alert={{ type: 'error', title: strings('Error connecting to your cluster'), body: err.toString() }} />
220+
<Alert
221+
className="top-pad"
222+
alert={{ type: 'error', title: strings('Error connecting to your cluster'), body: err.toString() }}
223+
/>
221224
)
222225
}
223226

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright 2020 The Kubernetes Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
type SessionInitStatus = 'NotYet' | 'InProgress' | 'Reinit' | 'Done' | 'Error'
18+
19+
export default SessionInitStatus

plugins/plugin-client-common/src/components/Client/TabContent.tsx

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import KuiContext from './context'
2121
const Confirm = React.lazy(() => import('../Views/Confirm'))
2222

2323
import getSize from '../Views/Terminal/getSize'
24+
import SessionInitStatus from './SessionInitStatus'
2425
import ScrollableTerminal, { TerminalOptions } from '../Views/Terminal/ScrollableTerminal'
2526

2627
type Cleaner = () => void
@@ -49,8 +50,6 @@ type Props = TabContentOptions &
4950
tabTitle?: string
5051
}
5152

52-
type SessionInitStatus = 'NotYet' | 'InProgress' | 'Reinit' | 'Done' | 'Error'
53-
5453
type State = Partial<WithTab> & {
5554
sessionInit: SessionInitStatus
5655
sessionInitError?: Error
@@ -243,38 +242,42 @@ export default class TabContent extends React.PureComponent<Props, State> {
243242
}
244243

245244
private terminal() {
246-
if (this.state.sessionInit !== 'Done') {
245+
if (this.state.sessionInit !== 'NotYet') {
247246
return (
248247
<KuiContext.Consumer>
249-
{config => {
250-
if (this.state.sessionInit === 'Error' && config.loadingError) {
251-
return config.loadingError(this.state.sessionInitError)
252-
} else if (this.state.sessionInit === 'Reinit' && config.reinit) {
253-
return config.reinit
254-
}
255-
256-
return config.loading || this.defaultLoading()
257-
}}
248+
{config => (
249+
<ScrollableTerminal
250+
{...this.props}
251+
tab={this.state.tab.current}
252+
sessionInit={this.state.sessionInit}
253+
config={config}
254+
toggleAttribute={this._toggleAttribute}
255+
onClear={this._onClear}
256+
ref={this.state._terminal}
257+
>
258+
{this.children()}
259+
</ScrollableTerminal>
260+
)}
258261
</KuiContext.Consumer>
259262
)
260-
} else {
263+
}
264+
}
265+
266+
/** Use client-provided (or default) proxy disconnected notice, if warranted */
267+
private proxyDisconnectNotice() {
268+
if (this.state.sessionInit !== 'Done') {
261269
return (
262-
<React.Fragment>
263-
<KuiContext.Consumer>
264-
{config => (
265-
<ScrollableTerminal
266-
{...this.props}
267-
tab={this.state.tab.current}
268-
config={config}
269-
toggleAttribute={this._toggleAttribute}
270-
onClear={this._onClear}
271-
ref={this.state._terminal}
272-
>
273-
{this.children()}
274-
</ScrollableTerminal>
275-
)}
276-
</KuiContext.Consumer>
277-
</React.Fragment>
270+
<KuiContext.Consumer>
271+
{config => (
272+
<React.Suspense fallback={<div />}>
273+
{this.state.sessionInit === 'Error' && config.loadingError
274+
? config.loadingError(this.state.sessionInitError)
275+
: this.state.sessionInit === 'Reinit' && config.reinit
276+
? config.reinit
277+
: this.state.sessionInit !== 'Done' && (config.loading || this.defaultLoading())}
278+
</React.Suspense>
279+
)}
280+
</KuiContext.Consumer>
278281
)
279282
}
280283
}
@@ -333,6 +336,7 @@ export default class TabContent extends React.PureComponent<Props, State> {
333336
return (
334337
<React.Fragment>
335338
<div className="kui--rows">
339+
{this.proxyDisconnectNotice()}
336340
<div className="kui--columns" style={{ position: 'relative' }}>
337341
{this.terminal()}
338342
</div>

plugins/plugin-client-common/src/components/Views/Terminal/ScrollableTerminal.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import getSize from './getSize'
5050
import SplitHeader from './SplitHeader'
5151
import { NotebookImpl, isNotebookImpl, snapshot, FlightRecorder, tabAlignment } from './Snapshot'
5252
import KuiConfiguration from '../../Client/KuiConfiguration'
53+
import SessionInitStatus from '../../Client/SessionInitStatus'
5354
import { onCopy, onCut, onPaste } from './ClipboardTransfer'
5455
import {
5556
Active,
@@ -121,6 +122,9 @@ type Props = TerminalOptions & {
121122

122123
/** Toggle attribute on Tab DOM */
123124
toggleAttribute(attr: string): void
125+
126+
/** Status of the proxy session (for client-server architectures of Kui) */
127+
sessionInit: SessionInitStatus
124128
}
125129

126130
interface State {
@@ -350,7 +354,7 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
350354
const scrollback = this.scrollback()
351355
const welcomeMax = this.props.config.showWelcomeMax
352356

353-
if (this.props.config.loadingDone && welcomeMax !== undefined) {
357+
if (this.props.sessionInit === 'Done' && this.props.config.loadingDone && welcomeMax !== undefined) {
354358
const welcomed = parseInt(localStorage.getItem(NUM_WELCOMED)) || 0
355359

356360
if ((welcomeMax === -1 || welcomed < welcomeMax) && this.props.config.loadingDone) {
@@ -1539,7 +1543,7 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
15391543

15401544
public render() {
15411545
return (
1542-
<div className="repl" id="main-repl">
1546+
<div className="repl" id="main-repl" data-session-init-status={this.props.sessionInit}>
15431547
<div className="repl-inner zoomable kui--terminal-split-container" data-split-count={this.state.splits.length}>
15441548
{this.state.splits.map((scrollback, sbidx) => this.split(scrollback, sbidx))}
15451549
</div>

plugins/plugin-client-common/web/scss/components/Alert/PatternFly.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@
1717
.kui--toolbar-alert {
1818
white-space: normal;
1919

20-
&.kui--connection-lost {
21-
position: absolute;
22-
}
23-
2420
h4 {
2521
margin: 0;
2622
font-size: inherit;

plugins/plugin-client-common/web/scss/components/Terminal/Announcement.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@
2222
background-color: var(--color-repl-background);
2323
}
2424
}
25+
26+
.repl:not([data-session-init-status='Done']) .kui--session-init-done {
27+
display: none;
28+
}

0 commit comments

Comments
 (0)