Skip to content

Commit

Permalink
fix: replace Containers with Logs tab
Browse files Browse the repository at this point in the history
this PR also fixes
- a few missing pieces to support Sidecar Toolbar updates from react components
- ability for PTY streaming consumers to direct xon/xoff flow control
- removes a number of way out of date css rules

Fixes #4603
  • Loading branch information
starpit committed May 17, 2020
1 parent 7d874a6 commit 00e8786
Show file tree
Hide file tree
Showing 31 changed files with 465 additions and 399 deletions.
5 changes: 5 additions & 0 deletions packages/core/src/core/jobs/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,10 @@ export interface Abortable {
abort(): void
}

export interface FlowControllable {
xon(): void
xoff(): void
}

/** in the future, a WatchableJob may be more than Abortable, e.g. Suspendable */
export type WatchableJob = Abortable
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export {
isMetadataBearing as isResourceWithMetadata
} from './models/entity'
export { isWatchable, Watchable, Watcher, WatchPusher } from './core/jobs/watchable'
export { Abortable } from './core/jobs/job'
export { Abortable, FlowControllable } from './core/jobs/job'
import { Tab } from './webapp/tab'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function History(tab: Tab) {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/models/execOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

import { ExecType } from './command'
import { Tab } from '../webapp/tab'
import { Streamable, StreamableFactory } from './streamable'
import { Stream, Streamable, StreamableFactory } from './streamable'
import { Block } from '../webapp/models/block'
import { Abortable } from '../core/jobs/job'
import { Abortable, FlowControllable } from '../core/jobs/job'

export interface ExecOptions {
/** force execution in a given tab? */
Expand Down Expand Up @@ -89,7 +89,7 @@ export interface ExecOptions {
stderr?: (str: string) => any // eslint-disable-line @typescript-eslint/no-explicit-any

/** on job init, pass the job, and get back a stdout */
onInit?: (job: Abortable) => (str: Streamable) => void
onInit?: (job: Abortable & FlowControllable) => Stream | Promise<Stream>

parameters?: any // eslint-disable-line @typescript-eslint/no-explicit-any
entity?: any // eslint-disable-line @typescript-eslint/no-explicit-any
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/models/streamable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ import { ScalarResponse } from './entity'
export type Streamable = ScalarResponse // SimpleEntity | Table | MixedResponse | MultiModalResponse
export default Streamable

export type Stream = (response: Streamable) => Promise<void>
export type Stream = (response: Streamable) => void | Promise<void>

export type StreamableFactory = () => Promise<Stream>
export type StreamableFactory = () => Stream | Promise<Stream>
13 changes: 11 additions & 2 deletions plugins/plugin-bash-like/src/pty/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ const remoteChannelFactory: ChannelFactory = async (tab: Tab) => {
const { proto, port, path, uid, gid } = resp.content
const protoHostPortContextRoot = window.location.href
.replace(/#?\/?$/, '')
.replace(/^http(s?):\/\/([^:/]+)(:\d+)?/, `${proto}://$2${port === -1 ? '$3' : ':'+port}`)
.replace(/^http(s?):\/\/([^:/]+)(:\d+)?/, `${proto}://$2${port === -1 ? '$3' : ':' + port}`)
.replace(/\/(index\.html)?$/, '')
const url = new URL(path, protoHostPortContextRoot).href
debug('websocket url', url, proto, port, path, uid, gid)
Expand Down Expand Up @@ -938,11 +938,20 @@ export const doExec = (

if (execOptions.onInit) {
const job = {
xon: () => {
debug('xon requested')
ws.send(JSON.stringify({ type: 'xon', uuid: ourUUID }))
},
xoff: () => {
debug('xoff requested')
ws.send(JSON.stringify({ type: 'xoff', uuid: ourUUID }))
},
abort: () => {
debug('abort requested')
ws.send(JSON.stringify({ type: 'kill', uuid: ourUUID }))
}
}
execOptions.stdout = execOptions.onInit(job)
execOptions.stdout = await execOptions.onInit(job)
}
}

Expand Down
18 changes: 18 additions & 0 deletions plugins/plugin-bash-like/src/pty/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,24 @@ export const onConnection = (exitNow: ExitHandler, uid?: number, gid?: number) =
} = JSON.parse(data)

switch (msg.type) {
case 'xon': {
const shell = msg.uuid && (await shells[msg.uuid])
if (shell) {
const RESUME = '\x11' // this is XON
shell.write(RESUME)
}
break
}

case 'xoff': {
const shell = msg.uuid && (await shells[msg.uuid])
if (shell) {
const PAUSE = '\x13' // this is XOFF
shell.write(PAUSE)
}
break
}

case 'kill': {
const shell = msg.uuid && (await shells[msg.uuid])
if (shell) {
Expand Down
15 changes: 3 additions & 12 deletions plugins/plugin-client-common/src/components/Content/Eval.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ import * as React from 'react'
import * as Debug from 'debug'

import {
ParsedOptions,
Tab as KuiTab,
ScalarResource,
SupportedStringContent,
MultiModalResponse,
isCommandStringContent,
FunctionThatProducesContent,
ReactProvider,
Expand All @@ -33,18 +30,12 @@ import {
} from '@kui-shell/core'

import { Loading } from '../../'
import KuiMMRContent from './KuiContent'
import KuiMMRContent, { KuiMMRProps } from './KuiContent'

const debug = Debug('plugins/sidecar/Eval')

interface EvalProps {
tab: KuiTab
interface EvalProps extends Omit<KuiMMRProps, 'mode'> {
command: string | FunctionThatProducesContent
args: {
argvNoOptions: string[]
parsedOptions: ParsedOptions
}
response: MultiModalResponse
contentType?: SupportedStringContent
}

Expand Down Expand Up @@ -129,6 +120,6 @@ export default class Eval extends React.PureComponent<EvalProps, EvalState> {
contentType: this.state.contentType
}

return <KuiMMRContent tab={this.props.tab} mode={mode} response={this.props.response} args={this.props.args} />
return <KuiMMRContent {...this.props} mode={mode} />
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import HTMLString from './HTMLString'
import HTMLDom from './Scalar/HTMLDom'
import RadioTableSpi from '../spi/RadioTable'

interface KuiMMRProps {
export interface KuiMMRProps {
tab: KuiTab
mode: Content
response: MultiModalResponse
Expand All @@ -55,7 +55,7 @@ interface KuiMMRProps {

export default class KuiMMRContent extends React.PureComponent<KuiMMRProps> {
public render() {
const { tab, mode, response, willUpdateToolbar, args } = this.props
const { tab, mode, response, willUpdateToolbar } = this.props

if (isStringWithOptionalContentType(mode)) {
if (mode.contentType === 'text/html') {
Expand All @@ -74,18 +74,16 @@ export default class KuiMMRContent extends React.PureComponent<KuiMMRProps> {
<Editor
content={mode}
readOnly={false}
willUpdateToolbar={willUpdateToolbar}
willUpdateToolbar={!response.toolbarText && willUpdateToolbar}
response={response}
repl={tab.REPL}
/>
)
}
} else if (isCommandStringContent(mode)) {
return (
<Eval tab={tab} command={mode.contentFrom} contentType={mode.contentType} response={response} args={args} />
)
return <Eval {...this.props} command={mode.contentFrom} contentType={mode.contentType} />
} else if (isFunctionContent(mode)) {
return <Eval tab={tab} command={mode.content} response={response} args={args} />
return <Eval {...this.props} command={mode.content} />
} else if (isScalarContent(mode)) {
if (isReactProvider(mode)) {
return mode.react({ willUpdateToolbar })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ export type Props = {
}
}

/** helper to ensure exhaustiveness of the switch statement below */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function assertUnreachable(x: never): never {
throw new Error('Did not expect to get here')
}

export default class Toolbar extends React.PureComponent<Props> {
private icon() {
if (this.props.toolbarText) {
Expand All @@ -40,9 +46,13 @@ export default class Toolbar extends React.PureComponent<Props> {
return <Icons icon="Info" />
case 'warning':
return <Icons icon="Warning" />
default:
case 'error':
return <Icons icon="Error" />
}

// this bit of magic ensures exhaustiveness of the switch;
// reference: https://stackoverflow.com/a/39419171
return assertUnreachable(type)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ import {
ArrowLeftIcon as Back,
ArrowRightIcon as Forward,
InfoCircleIcon as Info,
WarningTriangleIcon as Warning,
ExclamationTriangleIcon as Oops,
ExclamationTriangleIcon as Warning,
BombIcon as Oops,
ListIcon as List,
ThIcon as Grid,
CaretLeftIcon as PreviousPage,
Expand Down
93 changes: 93 additions & 0 deletions plugins/plugin-client-common/web/css/static/ansi_up.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright 2020 IBM Corporation
*
* 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.
*/

.ansi-black-fg {
color: var(--color-black);
}
.ansi-black-bg,
.ansi-bright-black-bg {
background-color: var(--color-black);
}

.ansi-bright-black-fg {
color: var(--color-text-02);
}
.ansi-bright-black-bg {
background-color: var(--color-text-02);
}

.ansi-red-fg,
.ansi-bright-red-fg {
color: var(--color-red);
}
.ansi-red-bg,
.ansi-bright-red-bg {
background-color: var(--color-red);
}

.ansi-green-fg,
.ansi-bright-green-fg {
color: var(--color-green);
}
.ansi-green-bg,
.ansi-bright-green-bg {
background-color: var(--color-green);
}

.ansi-yellow-fg,
.ansi-bright-yellow-fg {
color: var(--color-yellow);
}
.ansi-yellow-bg,
.ansi-bright-yellow-bg {
background-color: var(--color-yellow);
}

.ansi-blue-fg,
.ansi-bright-blue-fg {
color: var(--color-blue);
}
.ansi-blue-bg,
.ansi-bright-blue-bg {
background-color: var(--color-blue);
}

.ansi-magenta-fg,
.ansi-bright-magenta-fg {
color: var(--color-green);
}
.ansi-magenta-bg,
.ansi-bright-magenta-bg {
background-color: var(--color-green);
}

.ansi-cyan-fg,
.ansi-bright-cyan-fg {
color: var(--color-cyan);
}
.ansi-cyan-bg,
.ansi-bright-cyan-bg {
background-color: var(--color-cyan);
}

.ansi-white-fg,
.ansi-bright-white-fg {
color: var(--color-white);
}
.ansi-white-bg,
.ansi-bright-white-bg {
background-color: var(--color-white);
}
3 changes: 3 additions & 0 deletions plugins/plugin-client-common/web/css/static/repl.scss
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@
/* probably not 100% right, but: for pty output, don't show kui's "caret", since xtermjs has its own */
display: none;
}
.repl-block.processing .repl-input input {
color: var(--color-name);
}
.repl-block.processing .repl-result-spinner-inner {
/* animation: spin 750ms linear infinite; */
height: auto;
Expand Down
9 changes: 8 additions & 1 deletion plugins/plugin-client-common/web/css/static/sidecar-main.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
margin: 0.75em 0 0;
}

.kui--sidecar-text-content {
font-size: 0.875em;
}

.sidecar-bottom-stripe {
flex-basis: 2.5em;
display: flex;
Expand Down Expand Up @@ -88,7 +92,9 @@
fill: var(--color-sidecar-toolbar-foreground);
}
.sidecar-toolbar-text[data-type="warning"] svg path {
fill: var(--color-warning);
fill: var(--color-base0A);
stroke: var(--color-base00);
stroke-width: 4%;
}

.sidecar-toolbar-text[data-type="warning"] svg path[data-icon-path="inner-path"],
Expand All @@ -97,6 +103,7 @@
}
.sidecar-toolbar-text[data-type="error"] svg path {
fill: var(--color-error);
stroke: var(--color-base00);
}
.sidecar-toolbar-text:not([data-type]),
.sidecar-bottom-stripe-mode-bits.sidecar-bottom-stripe-button-container:empty {
Expand Down
Loading

0 comments on commit 00e8786

Please sign in to comment.