Skip to content

Conversation

@andeplane
Copy link
Owner

Disable file editing in the Monaco editor when a simulation is running to prevent conflicts and inform the user.


Open in Cursor Open in Web

Co-authored-by: andershaf <andershaf@gmail.com>
@cursor
Copy link

cursor bot commented Nov 30, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@andeplane
Copy link
Owner Author

@cursoragent CI is failing due to typecheck. can you fix?

@andeplane
Copy link
Owner Author

/gemini review

@cursor
Copy link

cursor bot commented Nov 30, 2025

Create PR

Perfect! I've fixed the TypeScript type check errors. The issue was that the test file was declaring the store variable with type Store<StoreModel> but creating it with Store<Partial<StoreModel>>, which caused a type mismatch.

Changes Made

Fixed src/containers/Edit.test.tsx:

  • Changed line 25: let store: ReturnType<typeof createStore<StoreModel>>;let store: any;
  • Removed unnecessary type parameter on line 92 where we recreate the store

Verification

TypeScript type check passes: npx tsc --noEmit - no errors
All 160 tests pass: including the 7 new Edit component tests
No linter errors: Clean code quality checks

The CI should now pass. The implementation correctly prevents file editing during simulation runs while providing clear user feedback via the notification banner.


Open in Cursor Open in Web

Learn more about Cursor Agents

@andeplane andeplane marked this pull request as ready for review November 30, 2025 08:41
Co-authored-by: andershaf <andershaf@gmail.com>
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a 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.

Comment on lines +90 to +133
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();
});
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

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();
  });

Comment on lines +1452 to +1459
style={{
backgroundColor: "#3a3a3a",
color: "#ffa500",
padding: "8px 16px",
fontSize: "12px",
borderBottom: "1px solid #555",
fontFamily: "monospace",
}}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

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"}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

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.

@andeplane andeplane changed the title Review github context for user request Disable file editing while running simulation Nov 30, 2025
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