Skip to content

Commit

Permalink
feat: add Stop Watching capability to WatchPane
Browse files Browse the repository at this point in the history
Fixes #4554
  • Loading branch information
myan9 authored and starpit committed May 15, 2020
1 parent 327917b commit 09043c1
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 13 deletions.
2 changes: 2 additions & 0 deletions packages/test/src/api/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,5 @@ export const WATCHER_N_TITLE = (N: number) => `${WATCHER_N(N)} ${_TABLE_TITLE}`
export const WATCHER_N_DROPDOWN = (N: number) => `${WATCHER_N(N)} .pf-c-dropdown button.pf-c-dropdown__toggle`
export const WATCHER_N_DROPDOWN_ITEM = (N: number, label: string) =>
`${WATCHER_N(N)} .pf-c-dropdown button.pf-c-dropdown__menu-item[data-mode="${label}"]`
export const WATCHER_N_CLOSE = (N: number) => WATCHER_N_DROPDOWN_ITEM(N, 'Stop watching')
export const WATCHER_N_SHOW_AS_TABLE = (N: number) => WATCHER_N_DROPDOWN_ITEM(N, 'Show as table')
3 changes: 2 additions & 1 deletion plugins/plugin-client-common/i18n/resources_en_US.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"ok": "ok",
"Show as table": "Show as table"
"Show as table": "Show as table",
"Stop watching": "Stop watching"
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,16 @@ export default class TabContent extends React.PureComponent<Props, State> {
}
}

private closeWatchPane() {
this.setState(curState => {
return {
activeView: curState.activeView === 'TerminalSidecarWatcher' ? 'TerminalPlusSidecar' : 'TerminalOnly',
watchPaneHasContent: false,
primaryHeight: Height.NotSplit
}
})
}

private onWillLoseFocus() {
if (this._terminal) {
this._terminal.doFocus()
Expand Down Expand Up @@ -376,7 +386,12 @@ export default class TabContent extends React.PureComponent<Props, State> {
className={this.state.primaryHeight === Height.NotSplit ? 'kui--watch-pane-closed' : undefined}
>
{this.leftRightSplit()}
<WatchPane uuid={this.props.uuid} tab={this.state.tab} openWatchPane={this.openWatchPane.bind(this)} />
<WatchPane
uuid={this.props.uuid}
tab={this.state.tab}
openWatchPane={this.openWatchPane.bind(this)}
closeWatchPane={this.closeWatchPane.bind(this)}
/>
</SplitPane>
)
}
Expand Down
34 changes: 30 additions & 4 deletions plugins/plugin-client-common/src/components/Views/WatchPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ interface Props {
uuid: string
tab: Tab
openWatchPane: () => void
closeWatchPane: () => void
}

interface HistoryEntry extends BaseHistoryEntry {
Expand Down Expand Up @@ -151,9 +152,16 @@ export default class WatchPane extends React.PureComponent<Props, State> {
}

/** `Card Actions`, will be rendred as `Dropdown` */
private actions(command: string) {
const watchInTerminal = { label: strings('Show as table'), handler: this.watchInTerminal.bind(this, command) }
return [watchInTerminal]
private actions(history: HistoryEntry, watcherIdx: number) {
const watchInTerminal = {
label: strings('Show as table'),
handler: this.watchInTerminal.bind(this, history.command)
}
const stopWatching = {
label: strings('Stop watching'),
handler: this.clearSubPane.bind(this, history.response, watcherIdx)
}
return [watchInTerminal, stopWatching]
}

/** render subpane header as Breadcrumb */
Expand All @@ -163,18 +171,36 @@ export default class WatchPane extends React.PureComponent<Props, State> {
return <Breadcrumb repl={this.props.tab.REPL} breadcrumbs={breadcrumbs.length > 0 && breadcrumbs} />
}

/** abort the watchable job and clear the watch pane */
private clearSubPane(response: Watchable, idx: number) {
// abort the watchable job
response.watch.abort()

// remove the history entry from circular buffer
this.state.history.popAt(idx)

// force re-rendering
this.forceUpdate()

// remove the watch pane if there's no watcher
if (!this.state.history || this.state.history.length === 0) {
this.props.closeWatchPane()
}
}

public render() {
return (
<div className="kui--watch-pane">
{this.state.history &&
this.state.history.length !== 0 &&
Array(this.capacity())
.fill(undefined)
.map((_, idx) => {
const history = this.state.history.peekAt(idx)
return (
<CardSpi
className={`kui--card kui--screenshotable kui--card-${idx + 1}`}
actions={history && this.actions(history.command)}
actions={history && this.actions(history, idx)}
header={history && this.header(history.response, idx)}
key={history ? history.key : idx}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ export default class CircularBuffer<T extends BaseHistoryEntry> {
return this.entries.findIndex(predicate)
}

public get peekAll() {
return this.entries
}

public update(idx: number, t: T) {
this.entries[idx] = this.entry(t)
this.activeIdx = idx
Expand All @@ -79,6 +75,18 @@ export default class CircularBuffer<T extends BaseHistoryEntry> {
this._length = Math.min(this._length + 1, this.entries.length)
}

/** pop the entry at idx */
public popAt(idx: number) {
while (idx < this._length - 1) {
this.entries[idx] = this.entry(this.entries[++idx])
}

delete this.entries[idx]
this.activeIdx = idx - 1
this.insertionIdx = idx % this.entries.length
this._length = this._length - 1
}

public hasLeft() {
return this.activeIdx > 0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export default class PatternflyCard extends React.PureComponent<Props, State> {
}

private renderDropDownItems(actions: Action[]) {
return actions.map(item => (
<DropdownItem key="action" component="button" onClick={item.handler} data-mode={item.label}>
return actions.map((item, idx) => (
<DropdownItem key={idx} component="button" onClick={item.handler} data-mode={item.label}>
{item.label}
</DropdownItem>
))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ const watchNS = function(this: Common.ISuite, kubectl: string) {
console.error('click showAsTable')
// click dropdown
await this.app.client.click(Selectors.WATCHER_N_DROPDOWN(1))
const showAsTableButton = Selectors.WATCHER_N_DROPDOWN_ITEM(1, 'Show as table')
const showAsTableButton = Selectors.WATCHER_N_SHOW_AS_TABLE(1)
await this.app.client.waitForVisible(showAsTableButton)

console.error('wait for table shown in terminal')
Expand Down Expand Up @@ -199,6 +199,12 @@ const watchNS = function(this: Common.ISuite, kubectl: string) {

// and, conversely, that watch had better eventually show Offline
await this.app.client.waitForExist(watchBadgeButOffline)

await this.app.client.waitForExist(Selectors.WATCHER_N_DROPDOWN(1))
await this.app.client.click(Selectors.WATCHER_N_DROPDOWN(1))
await this.app.client.waitForVisible(Selectors.WATCHER_N_CLOSE(1))
await this.app.client.click(Selectors.WATCHER_N_CLOSE(1))
await this.app.client.waitForExist(Selectors.WATCHER_N(1), 500, true)
} catch (err) {
await Common.oops(this, false)(err)
}
Expand Down

0 comments on commit 09043c1

Please sign in to comment.