Skip to content

Commit

Permalink
feat: SplitHeader should have a clear button
Browse files Browse the repository at this point in the history
  • Loading branch information
myan9 authored and k8s-ci-robot committed Jun 7, 2021
1 parent 9c262b7 commit 7d4456b
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 41 deletions.
1 change: 1 addition & 0 deletions packages/test/src/api/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export const SPLIT_N = (N: number, inverseColors = false) =>
`${SPLITS}:nth-child(${N})` + (inverseColors ? INVERTED_COLORS : '')
export const SPLIT_N_HEADER = (N: number) => `${SPLIT_N(N)} .kui--split-header`
export const SPLIT_N_CLOSE = (N: number) => `${SPLIT_N_HEADER(N)} .kui--split-close-button`
export const SPLIT_N_CLEAR = (N: number) => `${SPLIT_N_HEADER(N)} .kui--split-clear-button`
export const SPLIT_N_FOCUS = (N: number) => `${SPLITS}:nth-child(${N}) ${current(_PROMPT_BLOCK)} ${_PROMPT}`
export const SPLIT_N_OUTPUT = (N: number) => `${SPLITS}:nth-child(${N}) .repl-output`
export const CURRENT_PROMPT_BLOCK_FOR_SPLIT = (splitIndex: number) => `${SPLIT_N(splitIndex)} ${current(_PROMPT_BLOCK)}`
Expand Down
2 changes: 2 additions & 0 deletions plugins/plugin-client-common/i18n/resources_en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,7 @@
"Abort watcher": "Abort this watcher",
"Pause watcher": "Pause this watcher",
"Resume watcher": "Resume this watcher",
"Clear this split pane": "Clear this split pane",
"Close this split pane": "Close this split pane",
"Close watcher": "Close and terminate this watcher"
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
SnapshotRequestEvent
} from '@kui-shell/core'

import ScrollbackState, { ScrollbackOptions, Cleaner } from './ScrollbackState'
import Block from './Block'
import getSize from './getSize'
import SplitHeader from './SplitHeader'
Expand Down Expand Up @@ -76,8 +77,6 @@ import '../../../../web/scss/components/Terminal/_index.scss'

const strings = i18n('plugin-client-common')

type Cleaner = () => void

/** Hard limit on the number of Terminal splits */
const MAX_TERMINALS = 8

Expand Down Expand Up @@ -114,42 +113,6 @@ type Props = TerminalOptions & {
config: KuiConfiguration
}

type ScrollbackOptions = NewSplitRequest['options']
type ScrollbackState = ScrollbackOptions & {
uuid: string
blocks: BlockModel[]
forceMiniSplit: boolean

/** tab facade */
facade?: KuiTab

/** grab a ref to the active block, to help us maintain focus */
_activeBlock?: Block

/** Has the user clicked to focus on a block? */
focusedBlockIdx?: number

/** cleanup routines for this split */
cleaners: Cleaner[]

/**
* Block index (into this.blocks) to show in a MiniSplit. Must be a
* negative number, interpreted as an index from the end.
*/
showThisIdxInMiniSplit: number

/** Memoized handlers */
remove: () => void
onClick: (evt: React.MouseEvent<HTMLElement, MouseEvent>) => void
onFocus: (evt: React.FocusEvent) => void
onOutputRender: () => void
navigateTo: (dir: 'first' | 'last' | 'previous' | 'next') => void
setActiveBlock: (c: Block) => void
willFocusBlock: (evt: React.SyntheticEvent) => void
willRemoveBlock: (evt: React.SyntheticEvent, idx?: number) => void
willUpdateCommand: (idx: number, command: string) => void
}

interface State {
focusedIdx: number
splits: ScrollbackState[]
Expand Down Expand Up @@ -402,6 +365,7 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
showThisIdxInMiniSplit: -2,
blocks: this.restoreBlocks(sbuuid).concat([Active()]),
remove: undefined,
clear: undefined,
onClick: undefined,
onFocus: undefined,
onOutputRender: undefined,
Expand All @@ -425,6 +389,7 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
}

state.remove = () => this.removeSplit(sbuuid)
state.clear = () => this.clear(sbuuid)
state.onClick = () => {
if (getSelectionText().length === 0) {
const sbidx = this.findSplit(this.state, sbuuid)
Expand Down Expand Up @@ -1342,7 +1307,7 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
onClick={scrollback.onClick}
>
<React.Fragment>
{this.state.splits.length > 1 && <SplitHeader onRemove={scrollback.remove} />}
{this.state.splits.length > 1 && <SplitHeader onRemove={scrollback.remove} onClear={scrollback.clear} />}
<ul className="kui--scrollback-block-list">{this.blocks(tab, scrollback, sbidx)}</ul>
</React.Fragment>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2021 The Kubernetes Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { Tab as KuiTab, NewSplitRequest } from '@kui-shell/core'

import Block from './Block'
import { BlockModel } from './Block/BlockModel'

export type Cleaner = () => void

export type ScrollbackOptions = NewSplitRequest['options']

type ScrollbackState = ScrollbackOptions & {
uuid: string
blocks: BlockModel[]
forceMiniSplit: boolean

/** tab facade */
facade?: KuiTab

/** grab a ref to the active block, to help us maintain focus */
_activeBlock?: Block

/** Has the user clicked to focus on a block? */
focusedBlockIdx?: number

/** cleanup routines for this split */
cleaners: Cleaner[]

/**
* Block index (into this.blocks) to show in a MiniSplit. Must be a
* negative number, interpreted as an index from the end.
*/
showThisIdxInMiniSplit: number

/** Memoized handlers */
remove: () => void
clear: () => void
onClick: (evt: React.MouseEvent<HTMLElement, MouseEvent>) => void
onFocus: (evt: React.FocusEvent) => void
onOutputRender: () => void
navigateTo: (dir: 'first' | 'last' | 'previous' | 'next') => void
setActiveBlock: (c: Block) => void
willFocusBlock: (evt: React.SyntheticEvent) => void
willRemoveBlock: (evt: React.SyntheticEvent, idx?: number) => void
willUpdateCommand: (idx: number, command: string) => void
}

export default ScrollbackState
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,42 @@
import React from 'react'
import { i18n } from '@kui-shell/core'

import Icons from '../../spi/Icons'
import Tooltip from '../../spi/Tooltip'
import '../../../../web/scss/components/Terminal/SplitHeader.scss'

const strings = i18n('plugin-client-common')

interface Props {
onRemove(): void
onClear(): void
}

/** Render a header for the given split */
export default class SplitHeader extends React.PureComponent<Props> {
private closeButton() {
return (
<Tooltip markdown={strings('Close this split')}>
<Tooltip markdown={strings('Close this split pane')}>
<div className="kui--split-close-button" onClick={this.props.onRemove}>
&#x2A2F;
</div>
</Tooltip>
)
}

private clearButton() {
return (
<Tooltip markdown={strings('Clear this split pane')}>
<Icons className="kui--split-clear-button" icon="Clear" onClick={this.props.onClear} />
</Tooltip>
)
}

public render() {
return (
<div className="kui--split-header flex-layout kui--inverted-color-context">
<div className="flex-fill" />
{this.clearButton()}
{this.closeButton()}
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import React from 'react'

import {
EraserIcon as Clear,
CameraIcon as Screenshot,
CameraRetroIcon as ScreenshotInProgress,
CheckCircleIcon as Checkmark,
Expand Down Expand Up @@ -93,6 +94,8 @@ export default function PatternFly4Icons(props: Props) {
return <Copy {...props} />
case 'Edit':
return <Edit {...props} />
case 'Clear':
return <Clear {...props} />
case 'Error':
return <Oops {...props} />
case 'Eye':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type SupportedIcon =
| 'CodeBranch'
| 'Copy'
| 'Edit'
| 'Clear'
| 'Error'
| 'Eye'
| 'EyeSlash'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,22 @@
& > div {
color: var(--color-sidecar-toolbar-foreground);
}

& > svg {
fill: var(--color-sidecar-toolbar-foreground);
}
}

@include SplitHeaderClose {
padding: 3px;
padding: 2px;
&:hover {
cursor: pointer;
background-color: var(--color-table-border1);
}
}

@include SplitHeaderClear {
padding: 2px;
&:hover {
cursor: pointer;
background-color: var(--color-table-border1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,8 @@ $action-hover-delay: 210ms;
@content;
}
}
@mixin SplitHeaderClear {
.kui--split-clear-button {
@content;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,22 @@ export function closeViaButton(this: Common.ISuite, splitCount: number, inSplit:
.catch(Common.oops(this, true)))
}

/** Clear the split in the current tab by clicking the clear button */
export function clearViaButton(this: Common.ISuite, inSplit: number) {
const expectBlockCount = ReplExpect.blockCount.bind(this)

it(`should close the split via button in the current tab and expect blockCount=1`, () =>
this.app.client
.$(Selectors.SPLIT_N_CLEAR(inSplit))
.then(_ => _.click())
.then(async () => {
await expectBlockCount()
.inSplit(inSplit)
.is(1)
})
.catch(Common.oops(this, true)))
}

async function clickToFocus(this: Common.ISuite, toSplitIndex: number) {
console.error('1')
await this.app.client.$(Selectors.SPLIT_N_FOCUS(toSplitIndex)).then(_ => _.click())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { Common, CLI, ReplExpect, Selectors, Util } from '@kui-shell/test'
import {
close,
closeViaButton,
clearViaButton,
expectSplits,
focusAndValidate,
doSplitViaButton,
Expand Down Expand Up @@ -296,6 +297,7 @@ describe('split close and reopen', function(this: Common.ISuite) {

const expectBlockCount = ReplExpect.blockCount.bind(this)
const splitTheTerminalViaButton = splitViaButton.bind(this)
const clearTheSplitViaButton = clearViaButton.bind(this)
const count = expectSplits.bind(this)
const arr = [close.bind(this), closeViaButton.bind(this)]

Expand Down Expand Up @@ -328,6 +330,7 @@ describe('split close and reopen', function(this: Common.ISuite) {
}
})

clearTheSplitViaButton(3)
closeTheSplit(2, 3)
count(2)
closeTheSplit(1, 2)
Expand Down

0 comments on commit 7d4456b

Please sign in to comment.