Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add search functionality to Web UI and Connect ssh terminal #48776

Merged
merged 1 commit into from
Nov 20, 2024

Conversation

avatus
Copy link
Contributor

@avatus avatus commented Nov 12, 2024

This will add the xterm/search-addon addon to our terminals in the web UI ssh sessions as well as Connect. The design of the search UI was inspired by the native browser search in Chrome.

Originally, it was thought that the search addon came with a built-in UI but apparently that isn't the case, so we had to do it ourselves.

Screenshot 2024-11-11 at 6 21 28 PM

Screen.Recording.2024-11-07.at.4.50.01.PM.mov

closes: #38957

changelog: You can now search text within ssh sessions in the Web UI and Teleport Connect

Comment on lines 46 to 93
function search(value: string, prev?: boolean) {
if (!xTerm) {
return;
}
const match = theme.colors.terminal.brightYellow;
const activeMatch = theme.colors.terminal.yellow;
setSearchValue(value);

xTerm.search(value, prev, {
decorations: {
matchOverviewRuler: match,
activeMatchColorOverviewRuler: activeMatch,
matchBackground: match,
activeMatchBackground: activeMatch,
},
});
}

const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
search(e.target.value);
};

const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
search(e.currentTarget.value);
}
};

function searchNext() {
search(searchValue);
}

function searchPrevious() {
search(searchValue, true /* search for previous result */);
}

const onEscape = useCallback(() => {
onClose();
xTerm.clearSearch();
xTerm.term.focus();
}, [xTerm, onClose]);

const onSearchResultsChange = useCallback(
(resultIndex: number, resultCount: number) => {
setSearchResults({ resultIndex, resultCount });
},
[]
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has a mixture of const x = () => {}, function y() { } and const z = useCallback(() => {}, []) - we should be consistent. My personal preference is useCallback.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough. i prefer function y() but i use const when doing useCallback and then a few other cheeky bare const got thrown in there. i'll switch to const and useCallback when needed. thanks

@avatus
Copy link
Contributor Author

avatus commented Nov 12, 2024

rebased due to conflict. PR feedback handled here and on a930d3e

Copy link

🤖 Vercel preview here: https://docs-6wic0fycq-goteleport.vercel.app/docs/ver/preview

Copy link

🤖 Vercel preview here: https://docs-hyszxa56h-goteleport.vercel.app/docs/ver/preview

const isSearchKeyboardEvent = useCallback(
(e: KeyboardEvent) => {
return (
e.type === 'keydown' &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have this check in Web. Why is it needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just saw other spots in Connect focusing specifically on keydown, didn't think too much on it. I can remove as the method being called on true is idempotent and shouldn't matter on keyup/keydown or duplicates

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed in DMs, let's move this check to the TerminalSearch level.

Copy link

🤖 Vercel preview here: https://docs-hh226fzu8-goteleport.vercel.app/docs/ver/preview

return false;
}
// this escape is handled if pressing escape with the term focused
if (e.key === 'Escape') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we need the "global" Escape handler, some terminals only close the search when you have the input focused.
But if you want to keep it, we should run it only if the search is shown. Otherwise, we will intercept all Escape key events, even when we don't need them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you added a check in onKeyDown. However, this place doesn't need to care about it at all, onKeyDown is called only when the input is open.

But we still need to address the issue in registerCustomKeyEventHandler. We don't want to intercept Escape events when the search is closed.
I actually think we should remove closing the search from there. If you take a look at the file transfer, Escape closes it only when it is focused. I think it makes sense to have the same behavior for the search.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah i see. Ok, I've removed it from register and now only check in onKeyDown for the search input. also, I've remove dthe show check on that because onKeyDown can only be called when the input is showing anyway. Let me know if it's good now 👍

const isSearchKeyboardEvent = useCallback(
(e: KeyboardEvent) => {
return (
e.type === 'keydown' &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed in DMs, let's move this check to the TerminalSearch level.

docs/pages/connect-your-client/teleport-connect.mdx Outdated Show resolved Hide resolved
Copy link

🤖 Vercel preview here: https://docs-4jvhqgopl-goteleport.vercel.app/docs/ver/preview

Copy link

🤖 Vercel preview here: https://docs-pl6lbgnzq-goteleport.vercel.app/docs/ver/preview

Copy link
Contributor

@gzdunek gzdunek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some minor comments, we are almost there!

web/packages/shared/components/TerminalSearch/index.ts Outdated Show resolved Hide resolved
return false;
}
// this escape is handled if pressing escape with the term focused
if (e.key === 'Escape') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you added a check in onKeyDown. However, this place doesn't need to care about it at all, onKeyDown is called only when the input is open.

But we still need to address the issue in registerCustomKeyEventHandler. We don't want to intercept Escape events when the search is closed.
I actually think we should remove closing the search from there. If you take a look at the file transfer, Escape closes it only when it is focused. I think it makes sense to have the same behavior for the search.

Copy link

🤖 Vercel preview here: https://docs-6xbf6tt6p-goteleport.vercel.app/docs/ver/preview

Copy link
Contributor

@gzdunek gzdunek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some lasts comments.

🚢

*/

import { render, act, screen } from 'design/utils/testing';
import 'jest-canvas-mock';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 'jest-canvas-mock' and import '@testing-library/jest-dom' do nothing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they were used before but i dont think anything is needed with them now.

})),
}));

const createMockXTerm = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the references to xterm in tests/stories as well, I'd just name it terminalMock.

Comment on lines 124 to 131
}, [
onEscape,
onOpen,
searchInputRef,
terminalSearcher,
show,
isSearchKeyboardEvent,
]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some unnecessary deps:

Suggested change
}, [
onEscape,
onOpen,
searchInputRef,
terminalSearcher,
show,
isSearchKeyboardEvent,
]);
}, [isSearchKeyboardEvent, onOpen, terminalSearcher]);

@@ -27,6 +27,7 @@ import {
FileTransferRequests,
FileTransferContextProvider,
} from 'shared/components/FileTransfer';
import { TerminalSearch } from 'shared/components/TerminalSearch/TerminalSearch';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import { TerminalSearch } from 'shared/components/TerminalSearch/TerminalSearch';
import { TerminalSearch } from 'shared/components/TerminalSearch';

import {
FileTransferActionBar,
FileTransfer,
FileTransferContextProvider,
} from 'shared/components/FileTransfer';
import { TerminalSearch } from 'shared/components/TerminalSearch/TerminalSearch';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import { TerminalSearch } from 'shared/components/TerminalSearch/TerminalSearch';
import { TerminalSearch } from 'shared/components/TerminalSearch';

docs/pages/connect-your-client/teleport-connect.mdx Outdated Show resolved Hide resolved
@@ -254,6 +258,7 @@ const getDefaultKeymap = (
openProfiles: 'Ctrl+Shift+I',
terminalCopy: 'Ctrl+Shift+C',
terminalPaste: 'Ctrl+Shift+V',
terminalSearch: 'Ctrl+F',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just checked the terminal apps on Windows and Linux and they use Ctrl+Shift+F for search. I believe it's because Ctrl+F is used to move the cursor one character forward in bash. Please switch these shortcuts from Ctrl+F in Connect to Ctrl+Shift+F (and remember about updating the docs).

FYI we will have the same problem in Web UI where we overwrite Ctrl+F. We have no choice on Linux and Windows where this is a combination that opens the native search anyway. On macOS in theory we could only intercept Meta+F and leave Ctrl+F for the terminal, but I think we don't have a reliable way to test if the user is on Mac. So I guess we have to leave it as is.

@avatus
Copy link
Contributor Author

avatus commented Nov 20, 2024

@ryanclark im about to finish gz's last comments. anything left from you?

Copy link
Contributor

@ryanclark ryanclark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all good from me

Copy link

🤖 Vercel preview here: https://docs-g9ear6eqx-goteleport.vercel.app/docs

Merged via the queue into master with commit ad5963a Nov 20, 2024
42 of 43 checks passed
@avatus avatus deleted the avatus/search branch November 20, 2024 16:10
@public-teleport-github-review-bot

@avatus See the table below for backport results.

Branch Result
branch/v16 Failed
branch/v17 Create PR

avatus added a commit that referenced this pull request Nov 20, 2024
Backport #48776 to branch/v16

changelog: You can now search text within ssh sessions in the Web UI and
Teleport Connect
avatus added a commit that referenced this pull request Nov 20, 2024
Backport #48776 to branch/v16

changelog: You can now search text within ssh sessions in the Web UI and
Teleport Connect
github-merge-queue bot pushed a commit that referenced this pull request Nov 20, 2024
…9270)

Backport #48776 to branch/v16

changelog: You can now search text within ssh sessions in the Web UI and
Teleport Connect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Web UI does not provide the ability to search within an SSH session
3 participants