-
-
Notifications
You must be signed in to change notification settings - Fork 10
Disable file editing while running simulation #243
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
base: main
Are you sure you want to change the base?
Disable file editing while running simulation #243
Conversation
Co-authored-by: andershaf <andershaf@gmail.com>
|
Cursor Agent can help with this pull request. Just |
|
@cursoragent CI is failing due to typecheck. can you fix? |
|
/gemini review |
|
Perfect! I've fixed the TypeScript type check errors. The issue was that the test file was declaring the store variable with type Changes MadeFixed
Verification✅ TypeScript type check passes: The CI should now pass. The implementation correctly prevents file editing during simulation runs while providing clear user feedback via the notification banner. Learn more about Cursor Agents |
Co-authored-by: andershaf <andershaf@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request correctly disables editing in the Monaco editor when a simulation is running and displays a notification to the user. The changes are well-tested with a new test file that covers the new logic.
My review includes a few suggestions for improvement:
- In
src/containers/Edit.tsx, I've recommended extracting inline styles and a magic number into constants to improve maintainability and readability. Using a flexbox layout is also suggested as a more robust alternative for managing the editor's height. - In
src/containers/Edit.test.tsx, I've pointed out some code duplication in the test setup and suggested a way to refactor it for better clarity and maintainability.
Overall, the implementation is good and the tests are comprehensive. Addressing these points will make the code even better.
| it('should render "No file selected" when no file is selected', () => { | ||
| // Arrange | ||
| store = createStore({ | ||
| app: { | ||
| selectedFile: undefined, | ||
| setSelectedFile: vi.fn(), | ||
| setStatus: vi.fn(), | ||
| }, | ||
| simulation: { | ||
| running: false, | ||
| paused: false, | ||
| showConsole: false, | ||
| files: [], | ||
| lammpsOutput: [], | ||
| resetLammpsOutput: vi.fn(), | ||
| addLammpsOutput: vi.fn(), | ||
| setShowConsole: vi.fn(), | ||
| setPaused: vi.fn(), | ||
| setCameraPosition: vi.fn(), | ||
| setCameraTarget: vi.fn(), | ||
| setSimulation: vi.fn(), | ||
| setRunning: vi.fn(), | ||
| setFiles: vi.fn(), | ||
| setLammps: vi.fn(), | ||
| extractAndApplyAtomifyCommands: vi.fn(), | ||
| syncFilesWasm: vi.fn(), | ||
| syncFilesJupyterLite: vi.fn(), | ||
| run: vi.fn(), | ||
| newSimulation: vi.fn(), | ||
| reset: vi.fn(), | ||
| }, | ||
| } as any); | ||
|
|
||
| // Act | ||
| render( | ||
| <StoreProvider store={store}> | ||
| <Edit /> | ||
| </StoreProvider> | ||
| ); | ||
|
|
||
| // Assert | ||
| expect(screen.getByText('No file selected')).toBeInTheDocument(); | ||
| expect(screen.queryByTestId('monaco-editor')).not.toBeInTheDocument(); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case re-creates the entire store, which duplicates a lot of setup from the beforeEach block. To simplify this and avoid duplication, you can mutate the state of the existing store instance, similar to how it's done in other tests in this file. This makes the test suite cleaner and easier to maintain.
Note: Directly mutating the store's state via getState() is generally an anti-pattern, but since it's already used in this test file, this suggestion aims for consistency and reduction of duplicated code. A more robust long-term solution would be to use a test store factory function.
it('should render "No file selected" when no file is selected', () => {
// Arrange
store.getState().app.selectedFile = undefined;
// Act
render(
<StoreProvider store={store}>
<Edit />
</StoreProvider>
);
// Assert
expect(screen.getByText('No file selected')).toBeInTheDocument();
expect(screen.queryByTestId('monaco-editor')).not.toBeInTheDocument();
});
| style={{ | ||
| backgroundColor: "#3a3a3a", | ||
| color: "#ffa500", | ||
| padding: "8px 16px", | ||
| fontSize: "12px", | ||
| borderBottom: "1px solid #555", | ||
| fontFamily: "monospace", | ||
| }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better readability and maintainability, consider extracting these inline styles into a constant object. This separates styling concerns from the component's structure. If your project uses a CSS-in-JS library or CSS modules, that would be an even better approach.
Example:
const bannerStyle: React.CSSProperties = {
backgroundColor: "#3a3a3a",
color: "#ffa500",
padding: "8px 16px",
fontSize: "12px",
borderBottom: "1px solid #555",
fontFamily: "monospace",
};
const Edit = () => {
// ...
return (
// ...
{isRunning && (
<div style={bannerStyle}>
ⓘ File editing is disabled while simulation is running
</div>
)}
// ...
);
}| </div> | ||
| )} | ||
| <Editor | ||
| height={isRunning ? "calc(100vh - 33px)" : "100vh"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded value 33px is brittle. If the banner's styling (e.g., padding, font-size) changes, this value will need to be manually updated, which is error-prone.
It's better to either define it as a constant with an explanatory comment, or refactor the layout to use Flexbox to avoid calculating heights manually.
Example with a constant:
const BANNER_HEIGHT_PX = 33; // Corresponds to banner padding, font size, and border.
// ...
<Editor
height={isRunning ? `calc(100vh - ${BANNER_HEIGHT_PX}px)` : "100vh"}
//...
/>Example with Flexbox (more robust):
// Wrap the component's return in a flex container
<div style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
{isRunning && (
<div style={bannerStyle}>
ⓘ File editing is disabled while simulation is running
</div>
)}
<div style={{ flex: 1, position: 'relative' }}>
<Editor
height="100%" // The editor will fill the remaining space
// ... other props
/>
</div>
</div>The flexbox approach is recommended as it's more resilient to style changes.
Disable file editing in the Monaco editor when a simulation is running to prevent conflicts and inform the user.