Add search functionality to Web UI and Connect ssh terminal#48776
Add search functionality to Web UI and Connect ssh terminal#48776
Conversation
8bb4881 to
93d9d74
Compare
| 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 }); | ||
| }, | ||
| [] | ||
| ); |
There was a problem hiding this comment.
This has a mixture of const x = () => {}, function y() { } and const z = useCallback(() => {}, []) - we should be consistent. My personal preference is useCallback.
There was a problem hiding this comment.
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
86cd4df to
a930d3e
Compare
|
rebased due to conflict. PR feedback handled here and on a930d3e |
|
🤖 Vercel preview here: https://docs-6wic0fycq-goteleport.vercel.app/docs/ver/preview |
|
🤖 Vercel preview here: https://docs-hyszxa56h-goteleport.vercel.app/docs/ver/preview |
| const isSearchKeyboardEvent = useCallback( | ||
| (e: KeyboardEvent) => { | ||
| return ( | ||
| e.type === 'keydown' && |
There was a problem hiding this comment.
We don't have this check in Web. Why is it needed?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
As discussed in DMs, let's move this check to the TerminalSearch level.
|
🤖 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') { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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' && |
There was a problem hiding this comment.
As discussed in DMs, let's move this check to the TerminalSearch level.
|
🤖 Vercel preview here: https://docs-4jvhqgopl-goteleport.vercel.app/docs/ver/preview |
|
🤖 Vercel preview here: https://docs-pl6lbgnzq-goteleport.vercel.app/docs/ver/preview |
gzdunek
left a comment
There was a problem hiding this comment.
Left some minor comments, we are almost there!
| return false; | ||
| } | ||
| // this escape is handled if pressing escape with the term focused | ||
| if (e.key === 'Escape') { |
There was a problem hiding this comment.
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.
|
🤖 Vercel preview here: https://docs-6xbf6tt6p-goteleport.vercel.app/docs/ver/preview |
gzdunek
left a comment
There was a problem hiding this comment.
Left some lasts comments.
🚢
| */ | ||
|
|
||
| import { render, act, screen } from 'design/utils/testing'; | ||
| import 'jest-canvas-mock'; |
There was a problem hiding this comment.
I think 'jest-canvas-mock' and import '@testing-library/jest-dom' do nothing.
There was a problem hiding this comment.
they were used before but i dont think anything is needed with them now.
| })), | ||
| })); | ||
|
|
||
| const createMockXTerm = () => { |
There was a problem hiding this comment.
Let's remove the references to xterm in tests/stories as well, I'd just name it terminalMock.
| }, [ | ||
| onEscape, | ||
| onOpen, | ||
| searchInputRef, | ||
| terminalSearcher, | ||
| show, | ||
| isSearchKeyboardEvent, | ||
| ]); |
There was a problem hiding this comment.
There are some unnecessary deps:
| }, [ | |
| onEscape, | |
| onOpen, | |
| searchInputRef, | |
| terminalSearcher, | |
| show, | |
| isSearchKeyboardEvent, | |
| ]); | |
| }, [isSearchKeyboardEvent, onOpen, terminalSearcher]); |
| FileTransferRequests, | ||
| FileTransferContextProvider, | ||
| } from 'shared/components/FileTransfer'; | ||
| import { TerminalSearch } from 'shared/components/TerminalSearch/TerminalSearch'; |
There was a problem hiding this comment.
| import { TerminalSearch } from 'shared/components/TerminalSearch/TerminalSearch'; | |
| import { TerminalSearch } from 'shared/components/TerminalSearch'; |
| FileTransfer, | ||
| FileTransferContextProvider, | ||
| } from 'shared/components/FileTransfer'; | ||
| import { TerminalSearch } from 'shared/components/TerminalSearch/TerminalSearch'; |
There was a problem hiding this comment.
| import { TerminalSearch } from 'shared/components/TerminalSearch/TerminalSearch'; | |
| import { TerminalSearch } from 'shared/components/TerminalSearch'; |
| openProfiles: 'Ctrl+Shift+I', | ||
| terminalCopy: 'Ctrl+Shift+C', | ||
| terminalPaste: 'Ctrl+Shift+V', | ||
| terminalSearch: 'Ctrl+F', |
There was a problem hiding this comment.
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.
|
@ryanclark im about to finish gz's last comments. anything left from you? |
39f2cde to
71a9914
Compare
|
🤖 Vercel preview here: https://docs-g9ear6eqx-goteleport.vercel.app/docs |
Backport #48776 to branch/v16 changelog: You can now search text within ssh sessions in the Web UI and Teleport Connect
Backport #48776 to branch/v16 changelog: You can now search text within ssh sessions in the Web UI and Teleport Connect
This will add the
xterm/search-addonaddon 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.
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