Skip to content

RI-7936 Add CommandView component#5411

Merged
valkirilov merged 16 commits intomainfrom
fe/feature/RI-7936/command-view-component
Jan 29, 2026
Merged

RI-7936 Add CommandView component#5411
valkirilov merged 16 commits intomainfrom
fe/feature/RI-7936/command-view-component

Conversation

@valkirilov
Copy link
Copy Markdown
Member

@valkirilov valkirilov commented Jan 27, 2026

What

Created a simple component for showing code snippets, later to be used for the Vector Search feature:

  • a simple wrapper around Monaco editor
  • pass a command and render it in read-only mode
  • allow minimal customization of the component (show/hide line numbers)
  • allow inline copy of the command

PS: You can review the Storybook examples for more details and usage instructions.

yarn sb

And open http://localhost:6006/?path=/docs/pages-vector-search-components-commandview--docs in your browser.

Testing

The component comes with a very minimal API, you need to pass only the command:

<CommandView command="PASS THE COMMAND HERE" />
Light Dark
Screenshot 2026-01-27 at 15 28 35 Screenshot 2026-01-27 at 15 28 41

Copy command

There is an inline button that lets you copy the command.

Optional: You can attach a callback handler as well.

<CommandView 
    command="PASS THE COMMAND HERE" 
    onCopy={() => null}
/>
Copy Tooltip Copy Callback
Screenshot 2026-01-27 at 15 29 20 Screenshot 2026-01-27 at 15 29 28

Note

Low Risk
Low risk UI addition: new wrapper components and read-only Monaco configuration with unit tests/storybook; minimal impact beyond new exports in components/base.

Overview
Adds a new CodeEditor base component as a thin wrapper around react-monaco-editor, automatically deriving the Monaco theme from ThemeContext (with an override) and exporting it via components/base.

Introduces CommandView for Vector Search to display a command string in a read-only Monaco editor with optional line numbers and an inline CopyButton, plus Monaco option presets, Storybook stories, and unit tests covering rendering, language defaults/overrides, line-number toggling, and copy callback behavior.

Written by Cursor Bugbot for commit 0482118. This will update automatically on new commits. Configure here.

- a simple wrapper around Monaco editor
- pass a command and render it in read-only mode
- allow minimal customization of the component (show/hide line numbers)
- allow inline copy of the command

re RI-7936
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 27, 2026

Code Coverage - Frontend unit tests

St.
Category Percentage Covered / Total
🟢 Statements 82.83% 21174/25563
🟡 Branches 68.11% 8949/13140
🟡 Functions 78.05% 5795/7425
🟢 Lines 83.23% 20737/24915

Test suite run success

5553 tests passing in 708 suites.

Report generated by 🧪jest coverage report action from 0482118

@valkirilov valkirilov marked this pull request as ready for review January 27, 2026 15:00
@valkirilov valkirilov self-assigned this Jan 27, 2026
pawelangelow
pawelangelow previously approved these changes Jan 28, 2026
Copy link
Copy Markdown
Contributor

@pawelangelow pawelangelow left a comment

Choose a reason for hiding this comment

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

Perfect!

pd-redis
pd-redis previously approved these changes Jan 28, 2026
Copy link
Copy Markdown
Contributor

@pd-redis pd-redis left a comment

Choose a reason for hiding this comment

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

None of the comments are deal-breakers, that is why I approve this PR

Comment thread .storybook/preview.tsx Outdated
import Router from 'uiSrc/Router'
import { StyledContainer } from './helpers/styles'
import { GlobalStyles } from 'uiSrc/styles/globalStyles'
import MonacoEnvironmentInitializer from 'uiSrc/components/MonacoEnvironmentInitializer/MonacoEnvironmentInitializer'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am OK with this being setup here, but just for information, you can do the same per story, not necessarily on global level

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I agree, and initially tried that, but something failed. Anyway, I gave it another shot and now it worked as expected, so these helpers now live in the related story, instead of the global setup. c3e4a6a

Thanks for pointing it 👍

@@ -0,0 +1,47 @@
import { monaco as monacoEditor } from 'react-monaco-editor'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would much more prefer to have an abstraction around monaco.
I know we used on quite few places already

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I agree completely with that. Initially, that's what I went for - to see whether we already have such a component. And I see there's already a MonacoEditor component, but it's quite complex with editing, inline editor, and dedicated editor features. For CommandView, we need something simpler - a read-only code display.

So, the way I see this abstraction layer:

  • it should be something simple
  • it should cover everything that can be accepted by Monaco Editor, at this point it should be a pass-through for all props
  • still, it should be the central point, where all the core logic lives
  • and serve as a layer where we can apply some specific customizations (now and in the future)

Still, I come up with this simple draft (which I'm not sure brings the value you wanted, so that’s why I put it in a separate pull request). #5417

But basically, this is how I see it at this point:

  • start with something simple
  • replace it later on all places where we use Monaco
  • and leave it as the single abstraction point in the codebase

Comment on lines +27 to +37
const withFlexContainer = (Story: React.ComponentType) => (
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
}}
>
<Story />
</div>
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You can just merge the 2 decorators

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yup, simplified it. Thanks :) ca20324

@@ -0,0 +1,64 @@
import React, { useContext, useMemo, useRef } from 'react'
import ReactMonacoEditor, { monaco as monacoEditor } from 'react-monaco-editor'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same as above

Comment on lines +27 to +33
const editorOptions = useMemo(
() =>
merge({}, defaultMonacoOptions, COMMAND_VIEW_EDITOR_OPTIONS, {
lineNumbers: showLineNumbers ? 'on' : 'off',
}),
[showLineNumbers],
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of use memo, why not just export 2 kind of options from constants and choose based on showLineNumbers

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! You're right that with the current binary choice for showLineNumbers, exporting two pre-built variants from constants would be simpler and cleaner. And since this prop typically doesn't change during the component's lifecycle, useMemo is indeed a safeguard for a problem we may never encounter.

export const COMMAND_VIEW_OPTIONS = {
  withLineNumbers: { ...baseOptions, lineNumbers: 'on't },
  withoutLineNumbers: { ...baseOptions, lineNumbers: 'off' },
}

However, I decided to keep the merge approach with prop overrides for extensibility. Right now we only have a single config override, but I want to make it easy to add more in the future. With this pattern, adding another override is just one more line:

merge({}, defaultMonacoOptions, COMMAND_VIEW_EDITOR_OPTIONS, {
  lineNumbers: showLineNumbers ? 'on' : 'off',
  // wordWrap: enableWordWrap ? 'on' : 'off', // easy to add
  // and many more...
})

As for useMemo - normally I would drop it to keep things simpler, but I'm keeping it with the same reasoning. If we later introduce a prop that actually changes during the component's lifecycle, the safeguard is already in place.

}

return (
<S.EditorWrapper className={className} data-testid={dataTestId}>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would not provide default test id, this makes it possible to have same test id on the same screen

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done 👍 87f470e

…nt setup

- Updated the storybook for CommandView component to use a new decorator for Monaco environment initialization.
- Removed the previous Redis commands initializer and replaced it with Monaco setup for syntax highlighting.
- Ensured that Monaco components are properly rendered within the story context.

re #RI-7936
@valkirilov valkirilov dismissed stale reviews from pd-redis and pawelangelow via 3d70aa7 January 28, 2026 10:09
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Comment thread redisinsight/ui/src/pages/vector-search/components/CommandView/CommandView.tsx Outdated
Comment thread redisinsight/ui/src/pages/vector-search/components/CommandView/CommandView.tsx Outdated
…r references

- removed the editorRef and editorDidMount function as they were not utilized in this simple component

re #RI-7936
…egration

- Added CodeEditorWrapper component as a thin wrapper around the Monaco editor.
- Created corresponding types for props to allow future customization.
- Exported the new component and its types for use in other parts of the application.

re #RI-7936
@valkirilov valkirilov merged commit f7e0704 into main Jan 29, 2026
18 checks passed
@valkirilov valkirilov deleted the fe/feature/RI-7936/command-view-component branch January 29, 2026 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants