Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

Commit

Permalink
[v9] Backport Teleport Connect (1 of 5) (#762)
Browse files Browse the repository at this point in the history
* Add more tests to Teleterm (#601)

* add more tests to Teleterm

* Update command for generating gRPC files for Teleterm

* Add cluster context switching (#624)

* Add connections switcher (#647)

* Add keyboard support to `Connections` popover (#651)

* Add clusters picker (#668)

* Improve identity picker (#670)

* Reformat commandLauncher.ts

* Remove command palette commands from command launcher

The way their `run` function works conflicts with the new implementation
(it directly changes quickInputService's state), so we remove that in
this commit to have less to deal with in upcoming commits.

* Show autocomplete suggestions in command bar

This commit does not support actually choosing any suggestion yet, just
showing them in the UI.

* Remove code related to empty command bar item

Our new code isn't going to show anything when there are no matches.

* Remove old pickers, rename Item to Suggestion

* Autocomplete commands and ssh logins

* Ignore case for autocomplete

* Automatically append @ after ssh login suggestion

* QuickInputService.getAutocomplete: Return no-match on empty suggestions

This required adding all those mocks to the tests so that the returned
suggestions in some of the tests are not empty.

* Autocomplete ssh hostnames

* Open command bar commands in new local shell

* Append space after picking command suggestion

* Adjust how showing & hiding autocomplete works in command bar

1. Pressing Esc while suggestions are shown should first close the suggestions
and the second press should actually exit the input.

2. Picking a suggestion should close the autocomplete if we didn't append
anything to the token (see comment for details).

3. Typing something in the command bar should always show the autocomplete
in case there are suggestions to show.

Also remove unused call to setInputValue.

* Fix opening new terminal when there's no active document

* useQuickInput: Rename serviceQuickInput to quickInputService

* Include command to run in AutocompleteResult

* Create DocumentTshNode after executing "tsh ssh" in command bar

* Update teleterm styles (#674)

* Remove leftover cruft from quick pickers

* Launch unsupported invocations of tsh ssh in local shell

* add simple empty state to pickers

* adjust `QuickInput` to match designs

* always show active item in `QuickInputList`

* make middle part of `TopBar` central

Co-authored-by: Grzegorz Zdunek <[email protected]>
Co-authored-by: Grzegorz Zdunek <[email protected]>
  • Loading branch information
3 people authored Apr 27, 2022
1 parent fbe0904 commit 20bf8e2
Show file tree
Hide file tree
Showing 128 changed files with 5,086 additions and 1,595 deletions.
2 changes: 1 addition & 1 deletion packages/build/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@storybook/react": "^6.4.0",
"@testing-library/jest-dom": "^5.15.1",
"@testing-library/react": "^12.1.2",
"@types/jest": "^27.0.3",
"@types/jest": "^27.3.1",
"@types/lodash": "4.14.149",
"@types/node": "^16.11.10",
"@types/react": "^16.8.19",
Expand Down
16 changes: 15 additions & 1 deletion packages/design/src/Label/Label.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ const kind = ({ kind, theme }) => {
};
}

if (kind === 'success') {
return {
backgroundColor: theme.colors.success,
color: theme.colors.primary.contrastText,
};
}

// default is primary
return {
backgroundColor: theme.colors.secondary.main,
Expand All @@ -65,7 +72,14 @@ const Label = styled.div`
`;

Label.propTypes = {
kind: PropTypes.oneOf(['primary', 'secondary', 'warning', 'danger']),
kind: PropTypes.oneOf([
'primary',
'secondary',
'warning',
'danger',
'success',
]),
invert: PropTypes.oneOf([true, false]),
};

export default Label;
Expand Down
2 changes: 1 addition & 1 deletion packages/teleterm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ For quick restarts, that restarts all processes and `tsh` daemon, press `F6`.

```sh
$ cd teleport
$ make grpc
$ make grpc-teleterm
```

Resulting files both `nodejs` and `golang` can be found in `/teleport/lib/teleterm/api/protogen/` directory.
Expand Down
2 changes: 1 addition & 1 deletion packages/teleterm/src/mainProcess/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ConfigService } from '../services/config';
import { Kind } from 'teleterm/ui/services/docs/types';
import { Kind } from 'teleterm/ui/services/workspacesService';

export type RuntimeSettings = {
dev: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export type KeyboardShortcutType =
| 'tab-new'
| 'tab-previous'
| 'tab-next'
| 'focus-global-search';
| 'focus-global-search'
| 'toggle-connections'
| 'toggle-clusters'
| 'toggle-identity';

export type KeyboardShortcutsConfig = Record<KeyboardShortcutType, string>;

Expand All @@ -42,6 +45,9 @@ export const keyboardShortcutsConfigProvider: ConfigServiceProvider<KeyboardShor
'tab-previous': 'Control-Shift-Tab',
'tab-next': 'Control-Tab',
'focus-global-search': 'F1',
'toggle-connections': 'Command-O',
'toggle-clusters': 'Command-E',
'toggle-identity': 'Command-I',
};

const linuxShortcuts: KeyboardShortcutsConfig = {
Expand All @@ -59,6 +65,9 @@ export const keyboardShortcutsConfigProvider: ConfigServiceProvider<KeyboardShor
'tab-previous': 'Ctrl-PageUp',
'tab-next': 'Ctrl-PageDown',
'focus-global-search': 'F1',
'toggle-connections': 'Ctrl-O',
'toggle-clusters': 'Ctrl-E',
'toggle-identity': 'Ctrl-I',
};

switch (platform) {
Expand Down
4 changes: 4 additions & 0 deletions packages/teleterm/src/services/pty/ptyProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class PtyProcess extends EventEmitter {

this._process.onData(data => this._handleData(data));
this._process.onExit(ev => this._handleExit(ev));

if (this.options.initCommand) {
this._process.write(this.options.initCommand + '\r');
}
}

send(data: string) {
Expand Down
11 changes: 6 additions & 5 deletions packages/teleterm/src/services/pty/ptyService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function buildOptions(settings: RuntimeSettings, cmd: PtyCommand): PtyOptions {
args: [],
cwd: cmd.cwd,
env,
initCommand: cmd.initCommand,
};

case 'pty.tsh-kube-login':
Expand All @@ -93,13 +94,13 @@ function buildOptions(settings: RuntimeSettings, cmd: PtyCommand): PtyOptions {
env['TELEPORT_CLUSTER'] = cmd.leafClusterId;
}

const loginHost = cmd.login
? `${cmd.login}@${cmd.serverId}`
: cmd.serverId;

return {
path: settings.tshd.binaryPath,
args: [
`--proxy=${cmd.rootClusterId}`,
'ssh',
`${cmd.login}@${cmd.serverId}`,
],
args: [`--proxy=${cmd.rootClusterId}`, 'ssh', loginHost],
env,
};
default:
Expand Down
4 changes: 3 additions & 1 deletion packages/teleterm/src/services/pty/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export type PtyOptions = {
path: string;
args: string[] | string;
cwd?: string;
initCommand?: string;
};

export type PtyProcess = {
Expand All @@ -24,11 +25,12 @@ export type PtyServiceClient = {
export type ShellCommand = {
kind: 'pty.shell';
cwd?: string;
initCommand?: string;
};

export type TshLoginCommand = {
kind: 'pty.tsh-login';
login: string;
login?: string;
serverId: string;
rootClusterId: string;
leafClusterId?: string;
Expand Down
7 changes: 5 additions & 2 deletions packages/teleterm/src/ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import AppContextProvider from './appContextProvider';
import AppContext from './appContext';
import ThemeProvider from './ThemeProvider';
import { LayoutManager } from './LayoutManager';
import { AppInitializer } from 'teleterm/ui/AppInitializer';

const App: React.FC<{ ctx: AppContext }> = ({ ctx }) => {
const { appearance } = ctx.mainProcessClient.configService.get();
Expand All @@ -17,8 +18,10 @@ const App: React.FC<{ ctx: AppContext }> = ({ ctx }) => {
<DndProvider backend={HTML5Backend}>
<AppContextProvider value={ctx}>
<ThemeProvider appearanceConfig={appearance}>
<LayoutManager />
<ModalsHost />
<AppInitializer>
<LayoutManager />
<ModalsHost />
</AppInitializer>
</ThemeProvider>
</AppContextProvider>
</DndProvider>
Expand Down
18 changes: 18 additions & 0 deletions packages/teleterm/src/ui/AppInitializer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React, { ReactNode, useEffect } from 'react';
import { useAppContext } from 'teleterm/ui/appContextProvider';

interface AppInitializerProps {
children?: ReactNode;
}

export function AppInitializer(props: AppInitializerProps) {
const ctx = useAppContext();
useEffect(() => {
const { rootClusterUri } = ctx.statePersistenceService.getWorkspaces();
if (rootClusterUri) {
ctx.workspacesService.setActiveWorkspace(rootClusterUri);
}
}, []);

return <>{props.children}</>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const StyledNavButton = styled.button(props => {
padding: '0',
marginRight: '24px',
textDecoration: 'none',
fontWeight: '500',
fontWeight: props.active ? 700 : 400,
outline: 'inherit',
border: 'none',
backgroundColor: 'inherit',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
import Table, { Cell } from 'design/DataTable';
import * as types from 'teleterm/ui/services/clusters/types';
import { useApps, State } from './useApps';
import { renderLabelCell } from '../renderLabelCell';

export default function Container() {
const state = useApps();
Expand Down Expand Up @@ -66,9 +67,9 @@ export function AppList(props: State) {
isSortable: true,
},
{
key: 'tags',
key: 'labelsList',
headerText: 'Labels',
render: renderLabels,
render: renderLabelCell,
},
{
altKey: 'launch-btn',
Expand Down Expand Up @@ -108,17 +109,6 @@ const renderAppIcon = (app: types.Application) => {
);
};

const renderLabels = ({ labelsList }: types.Kube) => {
const labels = labelsList.map(l => `${l.name}:${l.value}`);
const $labels = labels.map(label => (
<Label mb="1" mr="1" key={label} kind="secondary">
{label}
</Label>
));

return <Cell>{$labels}</Cell>;
};

const renderAddress = (app: types.Application) => {
return <Cell>https://{app.publicAddr}</Cell>;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import Servers from './Servers';
import Databases from './Databases';
import Applications from './Applications';
import Kubes from './Kubes';
import ClusterSearch from './ClusterSearch';

export default function ClusterResources() {
const clusterCtx = useClusterContext();
Expand All @@ -40,7 +39,6 @@ export default function ClusterResources() {

return (
<StyledMain>
<ClusterSearch onChange={clusterCtx.changeSearchValue} />
<Flex mt={3} flexDirection="column">
<SideNav mb={2} />
<HorizontalSplit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ const Input = styled.input(props => {
color: theme.colors.text.primary,
width: '100%',
minHeight: '30px',
border: '1px solid',
borderColor: theme.colors.primary.lighter,
minWidth: '300px',
border: 'none',
outline: 'none',
borderRadius: '4px',
padding: '2px 12px',
'&:hover, &:focus': {
color: theme.colors.primary.contrastText,
background: theme.colors.primary.lighter,
borderColor: theme.colors.secondary.dark,
opacity: 1,
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ limitations under the License.

import React from 'react';
import { useDatabases, State } from './useDatabases';
import * as types from 'teleterm/ui/services/clusters/types';
import { Label, ButtonBorder } from 'design';
import { ButtonBorder } from 'design';
import Table, { Cell } from 'design/DataTable';
import { renderLabelCell } from '../renderLabelCell';

export default function Container() {
const state = useDatabases();
Expand All @@ -38,7 +38,7 @@ function DatabaseList(props: State) {
{
key: 'labelsList',
headerText: 'Labels',
render: renderLabels,
render: renderLabelCell,
},
{
altKey: 'connect-btn',
Expand All @@ -51,17 +51,6 @@ function DatabaseList(props: State) {
);
}

const renderLabels = ({ labelsList }: types.Kube) => {
const labels = labelsList.map(l => `${l.name}:${l.value}`);
const $labels = labels.map(label => (
<Label mb="1" mr="1" key={label} kind="secondary">
{label}
</Label>
));

return <Cell>{$labels}</Cell>;
};

function renderConnectButton(uri: string, connect: (uri: string) => void) {
return (
<Cell align="right">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ limitations under the License.
import React from 'react';
import { useKubes, State } from './useKubes';
import Table, { Cell } from 'design/DataTable';
import { Label, ButtonBorder } from 'design';
import * as types from 'teleterm/ui/services/clusters/types';
import { ButtonBorder } from 'design';
import { renderLabelCell } from '../renderLabelCell';

export default function Container() {
const state = useKubes();
Expand Down Expand Up @@ -70,14 +70,3 @@ export const renderConnectButtonCell = (
</Cell>
);
};

const renderLabelCell = ({ labelsList }: types.Kube) => {
const labels = labelsList.map(l => `${l.name}:${l.value}`);
const $labels = labels.map(label => (
<Label mb="1" mr="1" key={label} kind="secondary">
{label}
</Label>
));

return <Cell>{$labels}</Cell>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { useServers, State } from './useServers';
import * as types from 'teleterm/ui/services/clusters/types';
import Table, { Cell } from 'design/DataTable';
import { ButtonBorder, Label } from 'design';
import { renderLabelCell } from '../renderLabelCell';

export default function Container() {
const state = useServers();
Expand Down Expand Up @@ -58,17 +59,6 @@ function ServerList(props: State) {
);
}

const renderLabelCell = ({ labelsList }: types.Server) => {
const labels = labelsList.map(l => `${l.name}:${l.value}`);
const $labels = labels.map(label => (
<Label mb="1" mr="1" key={label} kind="secondary">
{label}
</Label>
));

return <Cell>{$labels}</Cell>;
};

const renderConnectCell = (
serverUri: string,
connect: (serverUri: string) => void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function SideNav(props: Props) {
const $items = items.map((item, index) => {
return (
<ClusterNavButton
py={1}
p={1}
my={1}
title={item.title}
to={item.to}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { makeLabelTag } from 'teleport/components/formatters';
import { Cell } from 'design/DataTable';
import { Label as SingleLabel } from 'design';
import { Label } from 'teleport/types';

export function renderLabelCell<T extends { labelsList: Label[] }>(props: T) {
const labels = props.labelsList.map(makeLabelTag);
const $labels = labels.map(label => (
<SingleLabel mb="1" mr="1" key={label} kind="secondary">
{label}
</SingleLabel>
));

return <Cell>{$labels}</Cell>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ export const Notfound = () => {

function renderState(state: ClustersServiceState) {
const appContext = new MockAppContext();
appContext.docsService.update = () => null;
appContext.workspacesService.getActiveWorkspaceDocumentService().update =
() => null;
appContext.clustersService.state = state;

const doc = {
Expand Down
Loading

0 comments on commit 20bf8e2

Please sign in to comment.