Skip to content

Conversation

@justinpark
Copy link
Member

@justinpark justinpark commented Dec 16, 2025

User description

SUMMARY

Doc Link

Following changes in the SQL Lab layout structure, the existing SQL Lab actions have been modified so that they are now arranged through the Extension Manager.

SQLLab_layout_extensions_-_Google_Docs

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Screenshot 2025-12-17 at 6 59 15 PM

TESTING INSTRUCTIONS

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

CodeAnt-AI Description

Pluggable SQL Lab panels and compact editor controls with new tests

What Changed

  • SQL Lab now renders extension-driven panels and status area via new view and menu extension components so right sidebar panels and a status bar can be provided by extensions.
  • The editor top bar and south-pane tabs accept extension-provided primary and secondary actions; default primary/secondary actions are rendered through MenuExtension so custom actions from extensions appear alongside built-in buttons.
  • Run, Save, Share, and Limit controls support a compact mode: run uses a compact icon/text presentation, save shows a split compact layout (including "Save dataset" menu), share shows an icon-only copy button, and the limit dropdown label changed to "Limit" with shorter numeric formatting (e.g., 10K).
  • Database selector supports a horizontal compact layout and the left bar uses a new hook to provide database/catalog/schema behavior; table selector and left sidebar preserve selection behavior.
  • Visual/UX tweaks: tab and editor styling refinements, Ace editor gutter stacking fixed, and several new unit tests for MenuExtension, ViewExtension, StatusBar, top bar, and database selector.

Impact

✅ Clearer extension-driven editor actions
✅ Shorter, icon-first toolbar for compact editor layouts
✅ Easier database selection in horizontal/compact UIs

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

await this.initializeExtension(extension);
}),
);
try {
Copy link
Member

Choose a reason for hiding this comment

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

Why do you need to add a try/catch here? Isn't this handled by the caller?

Copy link
Member Author

Choose a reason for hiding this comment

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

ops. it's not supposed to be here.

@justinpark justinpark force-pushed the feat--superset--extensions-actions branch from 6580e9e to 7aac09b Compare December 18, 2025 03:01
*/
export enum ViewContribution {
RightSidebar = 'sqllab.rightSidebar',
SouthPanels = 'sqllab.panels',
Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to rename this to Panels to match the identifier as the other ones.

`}
>
<ActionPanel viewId={ViewContribution.Editor} primary compactMode>
{defaultPrimaryActions}
Copy link
Member

Choose a reason for hiding this comment

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

I think primary actions should come before secondary actions like VSCode (different from what's in Kasia's prototype). We should also sort the actions based on their use. Run should be the first action on the left.

queryEditorId: string;
}

const StatusBar = ({ queryEditorId }: StatusBarProps) => {
Copy link
Member

Choose a reason for hiding this comment

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

The StatusBar component should not have any logic in itself part from rendering items on the left and right sides. It's a layout component that receives built-in and external extensions. One built-in extension is the Timer. It would also be nice to implement the Timer logic using the events from @apache-superset/core instead of depending on Redux.

@justinpark
Copy link
Member Author

justinpark commented Dec 31, 2025

@kasiazjc There was some feedback regarding the placement of the primary button at the top of the editor. First of all, I think the Run button is currently too far from the editor, which means the mouse has to travel quite a distance to click it.

527884141-1b353705-ffdd-4fbb-8333-74147cb4e192_png__1447×974_

That's why I placed the primary and secondary buttons at the top left corner, similar to other locations in the existing interface.
Additionally, in the case of the run button, when there is a range selection, it changes to "Run Selection," so placing only the icon may affect readability. I think the size should be minimized, but the label should still be maintained.
I would appreciate your thoughts on this change compared to the previous design.

updated run primary action layout:

Screenshot 2025-12-30 at 12 57 18 PM

updated south panel tabs:

Screenshot 2026-01-02 at 12 33 40 PM

@justinpark justinpark marked this pull request as ready for review December 31, 2025 20:13
@dosubot dosubot bot added change:frontend Requires changing the frontend sqllab Namespace | Anything related to the SQL Lab labels Dec 31, 2025
@codeant-ai-for-open-source codeant-ai-for-open-source bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Dec 31, 2025
@justinpark justinpark force-pushed the feat--superset--extensions-actions branch from 2132dd8 to 012da74 Compare December 31, 2025 20:57
@codeant-ai-for-open-source
Copy link
Contributor

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Missing guards / unsafe non-null assertion
    The code uses a non-null assertion when retrieving command contributions and then accesses command.icon and command.command without runtime checks. If getCommandContribution returns undefined or returns a command missing fields, this will throw at runtime. Consider adding guards and fallbacks so missing/invalid contributions don't crash the UI.

  • Missing guard on dispatch
    onDbChange calls dispatch(queryEditorSetDb(queryEditor, dbId)) without verifying queryEditor is defined. Other handlers (catalog/schema) guard the dispatch. If queryEditor can be undefined this may dispatch an action with an invalid payload and cause reducers or middleware to misbehave.

  • Potential type mismatch for DB list
    handleDbList is typed to accept a single DatabaseObject but immediately calls setDatabases(result) which (elsewhere) expects the full databases collection (likely a map or array). The parameter type may be incorrect and cause incorrect runtime behavior or wrong shape in the store.

  • Debounced callback cleanup
    The debounced callback setQueryEditorAndSaveSqlWithDebounce is created with lodash debounce inside a useMemo but there is no cancellation/cleanup when the component unmounts. This can lead to stale executions or memory leaks if the debounced function fires after the component has unmounted or after queryEditor changed.

  • Hotkeys not unbound
    Hotkeys bound with Mousetrap.bind(...) in an effect are not unbound when the component is no longer active or on cleanup. If isActive toggles multiple times or the component is remounted, duplicate bindings can accumulate and result in double-triggered commands.

queryEditorId,
queryState,
overlayCreateAsMenu,
runQuery,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: The component's props include allowAsync but the function does not destructure it from props, so allowAsync is not available inside the component; this leaves the prop unused and prevents forwarding it to runQuery, causing behavioral regression when callers rely on allowAsync. [logic error]

Severity Level: Minor ⚠️

Suggested change
runQuery,
allowAsync,
Why it matters? ⭐

The props interface includes allowAsync but the component does not destructure it, so any callers setting allowAsync will have no effect. This is a real behavioral regression risk and the suggested destructuring is the correct, minimal fix.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
**Line:** 102:102
**Comment:**
	*Logic Error: The component's props include `allowAsync` but the function does not destructure it from props, so `allowAsync` is not available inside the component; this leaves the prop unused and prevents forwarding it to `runQuery`, causing behavioral regression when callers rely on `allowAsync`.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

data-test="run-query-action"
onClick={() =>
onClick(shouldShowStopBtn, allowAsync, runQuery, stopQuery, logAction)
onClick(shouldShowStopBtn, runQuery, stopQuery, logAction)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: runQuery accepts an optional boolean (c?: boolean) but the call site now invokes runQuery with no argument; the new allowAsync prop should be forwarded to runQuery to preserve previous behavior — wrap runQuery in a lambda that passes allowAsync. [logic error]

Severity Level: Minor ⚠️

Suggested change
onClick(shouldShowStopBtn, runQuery, stopQuery, logAction)
onClick(shouldShowStopBtn, () => runQuery(allowAsync), stopQuery, logAction)
Why it matters? ⭐

runQuery has signature (c?: boolean) => void. The PR now calls runQuery with no args which can change behavior if callers expected allowAsync to be passed. Wrapping runQuery as () => runQuery(allowAsync) (and destructuring allowAsync) preserves prior semantics — this fixes a real logic issue.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
**Line:** 145:145
**Comment:**
	*Logic Error: `runQuery` accepts an optional boolean (`c?: boolean`) but the call site now invokes `runQuery` with no argument; the new `allowAsync` prop should be forwarded to `runQuery` to preserve previous behavior — wrap `runQuery` in a lambda that passes `allowAsync`.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

Comment on lines 47 to 51
setShowSave={() => true}
overlayMenu={overlayMenu}
onSaveAsExplore={onSaveAsExplore}
/>,
);

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: The tests call userEvent.click without awaiting it; modern userEvent calls are asynchronous and should be awaited to avoid flaky tests — convert userEvent.click(...) to await userEvent.click(...) wherever a click leads to DOM updates or assertions immediately afterward. [possible bug]

Severity Level: Critical 🚨

Suggested change
setShowSave={() => true}
overlayMenu={overlayMenu}
onSaveAsExplore={onSaveAsExplore}
/>,
);
await userEvent.click(caretBtn);
Why it matters? ⭐

userEvent.click is asynchronous in modern testing-library; awaiting it prevents race conditions between the click and subsequent assertions. This change reduces flakiness and is a correct improvement to the test.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
**Line:** 47:51
**Comment:**
	*Possible Bug: The tests call `userEvent.click` without awaiting it; modern userEvent calls are asynchronous and should be awaited to avoid flaky tests — convert `userEvent.click(...)` to `await userEvent.click(...)` wherever a click leads to DOM updates or assertions immediately afterward.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

Comment on lines 65 to +75
onClick={() => setShowSave(true)}
popupRender={() => overlayMenu}
popupRender={() => (
<Menu
items={[
{
label: t('Save dataset'),
key: 'save-dataset',
onClick: onSaveAsExplore,
},
]}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Logic bug: onClick={() => setShowSave(true)} is attached to the DropdownButton, so clicking the dropdown to open the menu will immediately open the save modal instead of waiting for the user to select the "Save dataset" menu item; move the setShowSave(true) call into the menu item's click handler (and ensure the menu item handler also calls onSaveAsExplore) so the modal opens only after selecting the menu action. [logic error]

Severity Level: Minor ⚠️

Suggested change
onClick={() => setShowSave(true)}
popupRender={() => overlayMenu}
popupRender={() => (
<Menu
items={[
{
label: t('Save dataset'),
key: 'save-dataset',
onClick: onSaveAsExplore,
},
]}
/>
popupRender={() => (
<Menu
items={[
{
label: t('Save dataset'),
key: 'save-dataset',
onClick: () => {
setShowSave(true);
onSaveAsExplore?.();
},
Why it matters? ⭐

The current code calls setShowSave(true) on the DropdownButton's onClick, so simply opening the dropdown will immediately open the save modal — that's a real UX/logic bug. Moving the setShowSave call into the menu item's onClick (and calling onSaveAsExplore there) fixes the behaviour so the modal opens only after the user selects the menu action.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
**Line:** 65:75
**Comment:**
	*Logic Error: Logic bug: `onClick={() => setShowSave(true)}` is attached to the `DropdownButton`, so clicking the dropdown to open the menu will immediately open the save modal instead of waiting for the user to select the "Save dataset" menu item; move the `setShowSave(true)` call into the menu item's click handler (and ensure the menu item handler also calls `onSaveAsExplore`) so the modal opens only after selecting the menu action.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

Comment on lines +97 to +100
(ExtensionsManager as any).instance = undefined;
});

afterEach(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Tests only null out the singleton ExtensionsManager.instance but do not call any cleanup on an existing instance, which can leave internal state, timers or subscriptions from a prior instance alive and cause test flakiness or memory leaks; call an explicit cleanup/dispose on any existing instance before resetting to undefined. [resource leak]

Severity Level: Minor ⚠️

Suggested change
(ExtensionsManager as any).instance = undefined;
});
afterEach(() => {
const existing = (ExtensionsManager as any).instance as ExtensionsManager | undefined;
if (existing && typeof (existing as any).dispose === 'function') {
(existing as any).dispose();
}
(ExtensionsManager as any).instance = undefined;
});
afterEach(() => {
const existing = (ExtensionsManager as any).instance as ExtensionsManager | undefined;
if (existing && typeof (existing as any).dispose === 'function') {
(existing as any).dispose();
}
Why it matters? ⭐

This is a sensible improvement for test hygiene. The current tests just null the singleton which can leave timers/subscriptions alive if the manager holds any. Calling a dispose (guarded by a typeof check) is defensive and won't change behavior when dispose is absent. It's not speculative — it prevents potential flakiness and memory leaks in long test runs.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
**Line:** 97:100
**Comment:**
	*Resource Leak: Tests only null out the singleton `ExtensionsManager.instance` but do not call any cleanup on an existing instance, which can leave internal state, timers or subscriptions from a prior instance alive and cause test flakiness or memory leaks; call an explicit cleanup/dispose on any existing instance before resetting to undefined.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

Comment on lines 194 to 198
rerender(
<ExtensionsProvider>
<ViewExtension viewId={VIEW_ID_B} />
</ExtensionsProvider>,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: In the rerender call you re-wrap the UI with a new ExtensionsProvider instance instead of relying on the original test wrapper; this can create nested/different provider instances and make the test behavior inconsistent — rerender with only the new ViewExtension element so the original wrapper remains in effect. [possible bug]

Severity Level: Critical 🚨

Suggested change
rerender(
<ExtensionsProvider>
<ViewExtension viewId={VIEW_ID_B} />
</ExtensionsProvider>,
);
rerender(<ViewExtension viewId={VIEW_ID_B} />);
Why it matters? ⭐

Correct — passing a new provider wrapper to rerender may create a different provider instance or nesting, altering context state and making the test flaky. Rerendering the inner component so the original test wrapper remains in effect is the correct and minimal fix.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
**Line:** 194:198
**Comment:**
	*Possible Bug: In the rerender call you re-wrap the UI with a new `ExtensionsProvider` instance instead of relying on the original test wrapper; this can create nested/different provider instances and make the test behavior inconsistent — rerender with only the new `ViewExtension` element so the original wrapper remains in effect.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.


render(<MenuExtension viewId={TEST_VIEW_ID} primary />);

const button = screen.getByText('test.action Title').closest('button')!;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Locating the primary action's button via .closest('button') on a text node can return null and cause a runtime error; use a role-based query that finds the actual button by accessible name to avoid a potential TypeError and make the test less brittle. [possible bug]

Severity Level: Critical 🚨

Suggested change
const button = screen.getByText('test.action Title').closest('button')!;
const button = screen.getByRole('button', { name: 'test.action Title' });
Why it matters? ⭐

The change makes the test more robust and idiomatic: querying by role with the accessible name avoids a potential null from .closest() and better reflects how users interact with the UI. It's a simple, valid improvement that doesn't change behaviour and reduces flakiness.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
**Line:** 217:217
**Comment:**
	*Possible Bug: Locating the primary action's button via `.closest('button')` on a text node can return null and cause a runtime error; use a role-based query that finds the actual button by accessible name to avoid a potential TypeError and make the test less brittle.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

Comment on lines +27 to +28
const contributions =
ExtensionsManager.getInstance().getViewContributions(viewId) || [];
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: The call to getViewContributions(viewId) || [] assumes the method returns an array or falsy value; if it returns a non-array truthy value the code will break when iterating. Coerce the result to an array (using Array.isArray) to ensure contributions is always an array. [type error]

Severity Level: Minor ⚠️

Suggested change
const contributions =
ExtensionsManager.getInstance().getViewContributions(viewId) || [];
const maybeContributions = ExtensionsManager.getInstance().getViewContributions(viewId);
const contributions = Array.isArray(maybeContributions) ? maybeContributions : [];
Why it matters? ⭐

Coercing the result with Array.isArray prevents runtime errors if getViewContributions unexpectedly returns a non-array truthy value. The improved code is a small, defensive fix that prevents .map from failing.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/components/ViewExtension/index.tsx
**Line:** 27:28
**Comment:**
	*Type Error: The call to `getViewContributions(viewId) || []` assumes the method returns an array or falsy value; if it returns a non-array truthy value the code will break when iterating. Coerce the result to an array (using `Array.isArray`) to ensure `contributions` is always an array.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

ExtensionsManager.getInstance().getViewContributions(viewId) || [];
const { getView } = useExtensionsContext();

return <>{contributions.map(contribution => getView(contribution.id))}</>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Rendering a list of views without stable React keys can produce UI bugs and warnings; mapping contributions directly to elements returns an array of children without keys which can cause incorrect element reuse and rendering issues. Wrap each rendered view in an element with a stable key (e.g., the contribution id) and guard against missing ids. [possible bug]

Severity Level: Critical 🚨

Suggested change
return <>{contributions.map(contribution => getView(contribution.id))}</>;
return (
<>
{contributions
.filter(contribution => contribution && typeof contribution.id !== 'undefined')
.map(contribution => (
<span key={String(contribution.id)}>{getView(contribution.id)}</span>
))}
</>
);
Why it matters? ⭐

Mapping an array of children without stable keys can produce React warnings and incorrect element reuse. The suggested change adds a stable key per item which addresses the real issue. Note: the proposed wrapper uses a which will add extra DOM; prefer using <React.Fragment key={...}> to avoid altering markup or ensure getView already returns keyed elements.

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/components/ViewExtension/index.tsx
**Line:** 31:31
**Comment:**
	*Possible Bug: Rendering a list of views without stable React keys can produce UI bugs and warnings; mapping `contributions` directly to elements returns an array of children without keys which can cause incorrect element reuse and rendering issues. Wrap each rendered view in an element with a stable `key` (e.g., the contribution id) and guard against missing ids.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

@codeant-ai-for-open-source
Copy link
Contributor

CodeAnt AI finished reviewing your PR.

Copy link
Contributor

@bito-code-review bito-code-review 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 Agent Run #bb862d

Actionable Suggestions - 4
  • superset-frontend/src/components/MenuExtension/index.tsx - 2
  • superset-frontend/src/SqlLab/components/StatusBar/index.tsx - 1
  • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx - 1
    • Invisible border due to missing style · Line 61-61
Additional Suggestions - 14
  • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts - 1
    • Type mismatch in test data · Line 199-199
      The test passes a single DatabaseObject to getDbList, but the setDatabases action expects an array of DatabaseObject. This type mismatch could cause the reducer to fail at runtime when processing databases. Pass an array instead and remove the 'as any' cast.
  • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts - 1
    • Type mismatch in onDbChange · Line 59-61
      The onDbChange function's parameter type doesn't match the expected (db: DatabaseObject) => void from DatabaseSelectorProps. This could lead to type inconsistencies when called by components like TableSelectorMultiple. Update to accept the full DatabaseObject for better type safety.
      Code suggestion
       suggestion
         const onDbChange = (db: DatabaseObject) => {
           dispatch(queryEditorSetDb(queryEditor, db.id));
         };
  • superset-frontend/src/components/MenuExtension/index.tsx - 1
    • Type Ignore Violation · Line 68-68
      The // @ts-ignore suppresses type checking, violating the no 'any' types rule; remove it after fixing the import.
  • superset-frontend/src/components/ViewExtension/index.tsx - 1
    • React Key Missing · Line 31-31
      The map function in the return statement lacks a key prop, which can lead to React rendering issues and console warnings. Add key={contribution.id} to each mapped element.
  • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx - 1
    • Unused prop in interface · Line 30-30
      The queryEditorId prop is defined in SqlEditorTopBarProps but not used in the component or passed to MenuExtension. This appears to be an unused parameter that could confuse maintainers. Consider removing it from the interface, component props, and the parent SqlEditor usage to keep the API clean.
  • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx - 1
    • Missing compactMode test coverage · Line 25-50
      The mock misses compactMode, so tests can't verify the component passes compactMode=true to primary MenuExtension, reducing coverage of prop forwarding.
  • superset-frontend/src/components/DatabaseSelector/types.ts - 1
    • Missing test coverage for horizontalMode · Line 51-51
      The new horizontalMode prop changes the component's layout from vertical to horizontal, but the existing tests don't cover this behavior. Consider adding a test to ensure the horizontal rendering works as expected.
  • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx - 4
    • Unnecessary Type Assertion · Line 93-93
      The `as any` assertion on ExtensionsProvider in the render wrapper is unnecessary, as React.FC is compatible with React.ComponentType. This violates the no-`any` rule and can be safely removed.
      Code suggestion
       @@ -92,3 +92,3 @@
        const renderWithExtensionsProvider = (ui: ReactElement) => {
      -  return render(ui, { wrapper: ExtensionsProvider as any });
      +  return render(ui, { wrapper: ExtensionsProvider });
        };
    • Type Safety Violation · Line 72-76
      The test accesses private properties `contextIndex` and `extensionContributions` on ExtensionsManager using `as any`, which violates the project's TypeScript standards prohibiting `any` types. While this enables testing of internal state, it reduces type safety and maintainability. Consider exposing a test-specific API or using spies on public methods to achieve the same test coverage without type assertions.
    • Redundant Provider Wrapping · Line 92-94
      The renderWithExtensionsProvider function wraps components with ExtensionsProvider, but the project's custom render (from spec/helpers/testing-library) already includes this provider. This creates unnecessary nesting and inconsistency. Consider using render directly for all tests.
    • Inconsistent Test Rendering · Line 194-198
      In the 'renders views for different viewIds independently' test, the initial render uses renderWithExtensionsProvider, but rerender manually wraps with ExtensionsProvider. This inconsistency could lead to unexpected behavior. Standardize on one approach.
  • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx - 1
    • Type Inconsistency in Number Formatter · Line 37-47
      The convertToShortNum function has inconsistent return types (number for small/large values, string for K/M), which reduces type safety. Make it always return string for consistency.
  • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx - 1
    • Potential layout issue with negative margin · Line 187-187
      The negative margin on .sql-container extends the element beyond its parent .north-pane, which may cause unexpected layout behavior. If this is intended for full-width editor, it's fine; otherwise, consider removing it.
  • superset-frontend/src/SqlLab/components/StatusBar/index.tsx - 1
    • Unused Type Definition · Line 39-41
      The StatusBarProps interface defines queryEditorId but the component function doesn't use it. If props are needed later, they can be added then; for now, this is unused code.
Review Details
  • Files reviewed - 29 · Commit Range: 8666ffd..012da74
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/DatabaseSelector/index.tsx
    • superset-frontend/src/components/DatabaseSelector/types.ts
    • superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuExtension/index.tsx
    • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Eslint (Linter) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

Comment on lines +64 to +67
const command =
ExtensionsManager.getInstance().getCommandContribution(
contribution.command,
)!;
Copy link
Contributor

Choose a reason for hiding this comment

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

Undefined Command Access

If getCommandContribution returns undefined, accessing command.icon will throw at runtime; add a guard or filter.

Code Review Run #bb862d


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Comment on lines +91 to +94
const command =
ExtensionsManager.getInstance().getCommandContribution(
contribution.command,
)!;
Copy link
Contributor

Choose a reason for hiding this comment

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

Undefined Command Access

If getCommandContribution returns undefined, accessing command.title will throw at runtime; add a guard or filter.

Code Review Run #bb862d


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

}

const StatusBar = () => (
<Container align="center" justify="space-bewteen">
Copy link
Contributor

Choose a reason for hiding this comment

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

CSS Property Typo

The justify prop has a typo: "space-bewteen" should be "space-between" to apply correct CSS flexbox justification and ensure proper horizontal spacing of status bar items.

Code Review Run #bb862d


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

border-top-color: ${({ theme }) => theme.colorPrimaryActive} !important;
border-right-color: ${({ theme }) => theme.colorPrimaryActive} !important;
box-shadow: 0 0 2px ${({ theme }) => theme.colorPrimaryActive} !important;
border-top: 2px;
Copy link
Contributor

@bito-code-review bito-code-review bot Dec 31, 2025

Choose a reason for hiding this comment

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

Invisible border due to missing style

The CSS shorthand 'border-top: 2px;' sets the width but defaults the style to 'none', preventing any visible border from rendering. Since 'border-top-color' is already set to the theme's primary active color, adding 'solid' to the shorthand will make the intended 2px top border appear for active tabs.

Review Rule
Bito created the rule Incomplete CSS Border Shorthand Declaration for repo: apache/superset, language: TSX. Bito will avoid suggestions that match this rule. You can manage review rules here.
Code Review Run #bb862d

Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

@bito-code-review
Copy link
Contributor

bito-code-review bot commented Jan 2, 2026

Code Review Agent Run #1bc81b

Actionable Suggestions - 0
Review Details
  • Files reviewed - 29 · Commit Range: 012da74..fc08d15
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/DatabaseSelector/index.tsx
    • superset-frontend/src/components/DatabaseSelector/types.ts
    • superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuExtension/index.tsx
    • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

@bito-code-review
Copy link
Contributor

bito-code-review bot commented Jan 2, 2026

Code Review Agent Run #6ebfcc

Actionable Suggestions - 0
Review Details
  • Files reviewed - 29 · Commit Range: fc08d15..0b134bf
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/DatabaseSelector/index.tsx
    • superset-frontend/src/components/DatabaseSelector/types.ts
    • superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuExtension/index.tsx
    • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

@codeant-ai-for-open-source
Copy link
Contributor

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

}
return runQuery(false);
if (isStopAction) return stopQuery();
runQuery();
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed allowAsync since runQuery does not reference the value anymore.

const runQuery = () => {
if (database) {
startQuery();
}
};

@bito-code-review
Copy link
Contributor

bito-code-review bot commented Jan 2, 2026

Code Review Agent Run #5bbb49

Actionable Suggestions - 0
Additional Suggestions - 2
  • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx - 1
    • Potential visual regression in ACE editor · Line 290-290
      Removing z-index from the ACE editor gutter CSS may cause visual stacking issues, potentially making the gutter appear behind other elements. This changes observable program behavior by altering the UI layout. Consider reverting or verifying the necessity of this z-index for ACE editor theming.
  • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx - 1
    • Dead code removal · Line 729-729
      The allowAsync prop is being removed from RunQueryActionButton, but this prop isn't defined in the component's interface or used in its implementation. Removing it cleans up dead code without affecting behavior.
Review Details
  • Files reviewed - 30 · Commit Range: 0b134bf..0cc68b7
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/RunQueryActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/DatabaseSelector/index.tsx
    • superset-frontend/src/components/DatabaseSelector/types.ts
    • superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuExtension/index.tsx
    • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

@apache apache deleted a comment from codeant-ai-for-open-source bot Jan 2, 2026
@apache apache deleted a comment from codeant-ai-for-open-source bot Jan 2, 2026
@bito-code-review
Copy link
Contributor

bito-code-review bot commented Jan 2, 2026

Code Review Agent Run #b83feb

Actionable Suggestions - 0
Review Details
  • Files reviewed - 30 · Commit Range: 0cc68b7..2275873
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/RunQueryActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/DatabaseSelector/index.tsx
    • superset-frontend/src/components/DatabaseSelector/types.ts
    • superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuExtension/index.tsx
    • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

@codeant-ai-for-open-source
Copy link
Contributor

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@bito-code-review
Copy link
Contributor

bito-code-review bot commented Jan 3, 2026

Code Review Agent Run #97d76c

Actionable Suggestions - 0
Review Details
  • Files reviewed - 31 · Commit Range: 2275873..061b7f4
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/EstimateQueryCostButton/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/RunQueryActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/DatabaseSelector/index.tsx
    • superset-frontend/src/components/DatabaseSelector/types.ts
    • superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuExtension/index.tsx
    • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

@michael-s-molina michael-s-molina moved this from In Progress to In Review in Superset Extensions Jan 5, 2026
@michael-s-molina
Copy link
Member

Thank you for the latest changes @justinpark. I have some design suggestions that could be addressed in follow-up PRs but I think it would be easier to do them in this PR so that @kasiazjc can review the final form of the screen.

Screenshot 2026-01-05 at 11 10 42
  1. I think the tabs and buttons are a little too big and taking more vertical space than needed. My suggestion would be to use a smaller size to all.
  2. The vertical blank space in the editor, reserved for the line numbers, is a little confusing given that we're using the white/grey contrast to separate part of the screen. My suggestion would use the same background as the rest of the editor and add a separator.
  3. The editor's handle to drag has a darker background when comparing with the editor's background, creating the illusion of a border. I would use the same background color.
  4. Given that the editor is grey, I would use a white background for the panels to give more contrast.

Something like this:

Screenshot 2026-01-05 at 11 51 10

@kasiazjc These are just suggestions and I bet you can get to something even better.

Comment on lines 39 to 41
export interface StatusBarProps {
queryEditorId: string;
}
Copy link
Member

Choose a reason for hiding this comment

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

Unused currently.

Suggested change
export interface StatusBarProps {
queryEditorId: string;
}

viewId: string;
}

const ViewExtension = ({ viewId }: ViewExtensionProps) => {
Copy link
Member

Choose a reason for hiding this comment

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

The name ViewExtension is a bit misleading as it receives a viewId but returns a list of views.

</Splitter.Panel>
)}
</Splitter>
{statusBarContributions.length > 0 && <StatusBar />}
Copy link
Member

Choose a reason for hiding this comment

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

Inside StatusBar you're also checking the contributions registry. I wonder if we should let StatusBar render the registry lookup and render as null if needed instead of duplicating the logic here.

setShowSave: (arg0: boolean) => void;
overlayMenu: JSX.Element | null;
onSaveAsExplore?: () => void;
compactMode?: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

compactMode comes from SaveQuery which always sets it to true. Should we remove it?

interface ShareSqlLabQueryProps {
queryEditorId: string;
addDangerToast: (msg: string) => void;
compactMode?: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

Same here. compactMode is always true.

${({ theme }) => `
const DatabaseSelectorWrapper = styled.div<{ horizontal?: boolean }>`
${({ theme, horizontal }) =>
horizontal
Copy link
Member

Choose a reason for hiding this comment

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

I was not able to find any place in the code setting DatabaseSelector's horizontalMode. Should we remove the property?

@rusackas rusackas requested a review from kasiazjc January 5, 2026 18:31
@apache apache deleted a comment from codeant-ai-for-open-source bot Jan 5, 2026
@apache apache deleted a comment from codeant-ai-for-open-source bot Jan 5, 2026
@justinpark justinpark force-pushed the feat--superset--extensions-actions branch from 061b7f4 to c689c41 Compare January 7, 2026 19:58
@codeant-ai-for-open-source
Copy link
Contributor

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@netlify
Copy link

netlify bot commented Jan 7, 2026

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit c689c41
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/695ebb0282e542000869c057
😎 Deploy Preview https://deploy-preview-36644--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

@bito-code-review bito-code-review 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 Agent Run #09d82e

Actionable Suggestions - 7
  • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx - 1
  • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx - 1
  • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts - 5
Additional Suggestions - 10
  • superset-frontend/src/components/MenuExtension/index.tsx - 1
    • Inconsistent null handling · Line 60-85
      In primaryActions, there's no null check for command, unlike secondaryActions. If getCommandContribution returns null despite the ! assertion, it could cause runtime errors accessing command.icon. Add the check for consistency and safety.
  • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts - 2
    • Type Safety Risk · Line 89-89
      The type cast `result as unknown as Database[]` bypasses TypeScript's type checking, which could lead to runtime errors if DatabaseObject and Database have incompatible structures. Consider verifying type compatibility or using a type guard.
    • Misleading Naming · Line 102-102
      The variable name 'bool' is misleading since it holds a string (or null) from URLSearchParams.get('db'), not a boolean. A more descriptive name would improve readability.
  • superset-frontend/src/components/ViewExtension/index.tsx - 1
    • Missing React key in map · Line 31-31
      The map over contributions lacks a key prop on the returned elements, which will trigger React console warnings and may cause inefficient re-renders. Consider wrapping getView(contribution.id) in ... and importing React if needed.
  • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx - 1
    • Incomplete number formatting · Line 37-48
      The convertToShortNum function should format all large numbers, including billions, and return a consistent string type to avoid potential type issues in usage.
      Code suggestion
       @@ -37,12 +37,14 @@
      - export function convertToShortNum(num: number) {
      -   if (num < 1000) {
      -     return num;
      -   }
      -   if (num < 1_000_000) {
      -     return `${num / 1000}K`;
      -   }
      -   if (num < 1_000_000_000) {
      -     return `${num / 1000_000}M`;
      -   }
      -   return num;
      - }
      + export function convertToShortNum(num: number) {
      +   if (num < 1000) {
      +     return num.toString();
      +   }
      +   if (num < 1_000_000) {
      +     return `${num / 1000}K`;
      +   }
      +   if (num < 1_000_000_000) {
      +     return `${num / 1000_000}M`;
      +   }
      +   if (num < 1_000_000_000_000) {
      +     return `${num / 1_000_000_000}B`;
      +   }
      +   return num.toString();
      + }
  • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts - 2
    • Unnecessary rerender · Line 81-105
      rerender() not needed; effect sets db on initial render. Remove for clarity.
      Code suggestion
       diff --git a/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts b/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
       index 0000000..0000000 100644
      --- a/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
      +++ b/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
       @@ -91,10 +91,7 @@ test('returns database when dbId exists in store', () => {
          const { result, rerender } = renderHook(
            () => useDatabaseSelector(defaultQueryEditor.id),
            {
              wrapper: createWrapper({
                useRedux: true,
                store,
              }),
            },
          );
       
      -  // Trigger effect by rerendering
      -  rerender();
      -
          expect(result.current.db).toEqual(mockDatabase);
        });
    • Unnecessary rerender · Line 238-276
      rerender() unnecessary; effect sets db from localStorage on mount. Remove.
      Code suggestion
       diff --git a/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts b/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
       index 0000000..0000000 100644
      --- a/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
      +++ b/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
       @@ -254,8 +254,6 @@ test('reads database from localStorage when URL has db param', () => {
          const { result, rerender } = renderHook(
            () => useDatabaseSelector(defaultQueryEditor.id),
            {
              wrapper: createWrapper({
                useRedux: true,
                store,
              }),
            },
          );
       
      -  rerender();
      -
          expect(result.current.db).toEqual(localStorageDb);
          expect(localStorageHelpers.setItem).toHaveBeenCalledWith(
            localStorageHelpers.LocalStorageKeys.Database,
            null,
          );
        });
  • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx - 1
    • Incomplete Test Coverage · Line 38-43
      The test suite covers rendering when status bar contributions are present, but misses the conditional branch where no contributions exist, potentially leaving untested logic in the component's fragment return.
  • superset-frontend/src/SqlLab/components/SouthPane/index.tsx - 1
    • Hardcoded padding value · Line 231-231
      The padding in the Flex component uses a hardcoded `8px` value. For consistency with the theme, consider using `theme.sizeUnit` instead.
  • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx - 1
    • Unnecessary Type Cast · Line 93-93
      The 'as any' cast on ExtensionsProvider is unnecessary, as React.FC components are compatible with the render wrapper. Removing it improves type safety.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx - 1
Review Details
  • Files reviewed - 29 · Commit Range: 9512504..c689c41
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/EstimateQueryCostButton/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/RunQueryActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuExtension/index.tsx
    • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

Comment on lines +324 to 326
fireEvent.click(await findByText('Limit'));
expect(await findByText('10 000')).toBeInTheDocument();
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Test assertion mismatch

The change to findByText('Limit') correctly updates the test to match the component's button text, but the related assertion on line 326 expects '10 000' while the component renders '10 000 ' (with trailing space) in the dropdown options. This could cause the test to fail after opening the dropdown.

Code suggestion
Check the AI-generated fix before applying
Suggested change
fireEvent.click(await findByText('Limit'));
expect(await findByText('10 000')).toBeInTheDocument();
});
fireEvent.click(await findByText('Limit'));
expect(await findByText('10 000 ')).toBeInTheDocument();
});
Citations

Code Review Run #09d82e


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Comment on lines 194 to 198
rerender(
<ExtensionsProvider>
<ViewExtension viewId={VIEW_ID_B} />
</ExtensionsProvider>,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Test Logic Bug

The rerender in this test incorrectly wraps the component with ExtensionsProvider again, leading to double wrapping since the initial render already uses this wrapper. This could cause unexpected behavior in context or state. Change to rerender() instead.

Code Review Run #09d82e


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Comment on lines +107 to +130
test('dispatches QUERY_EDITOR_SETDB action on onDbChange', () => {
const store = mockStore(createInitialState());
const { result } = renderHook(
() => useDatabaseSelector(defaultQueryEditor.id),
{
wrapper: createWrapper({
useRedux: true,
store,
}),
},
);

act(() => {
result.current.onDbChange({ id: 2 });
});

const actions = store.getActions();
expect(actions).toContainEqual(
expect.objectContaining({
type: 'QUERY_EDITOR_SETDB',
dbId: 2,
}),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Incomplete dispatch assertion

Test checks dispatch type but not payload.dbId. Add expect.objectContaining({ dbId: 2 }).

Code suggestion
Check the AI-generated fix before applying
 --- a/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 +++ b/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 @@ -124,6 +124,7 @@ test('dispatches QUERY_EDITOR_SETDB action on onDbChange', () => {
    expect(actions).toContainEqual(
      expect.objectContaining({
        type: 'QUERY_EDITOR_SETDB',
 +      dbId: 2,
      }),
    );
  });
Citations

Code Review Run #09d82e


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Comment on lines +132 to +154
test('dispatches queryEditorSetCatalog action on onCatalogChange', () => {
const store = mockStore(createInitialState());
const { result } = renderHook(
() => useDatabaseSelector(defaultQueryEditor.id),
{
wrapper: createWrapper({
useRedux: true,
store,
}),
},
);

act(() => {
result.current.onCatalogChange('new_catalog');
});

const actions = store.getActions();
expect(actions).toContainEqual(
expect.objectContaining({
type: 'QUERY_EDITOR_SET_CATALOG',
}),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Incomplete dispatch assertion

Test checks type but not payload.catalog. Add expect.objectContaining({ catalog: 'new_catalog' }).

Code suggestion
Check the AI-generated fix before applying
 --- a/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 +++ b/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 @@ -149,6 +149,7 @@ test('dispatches queryEditorSetCatalog action on onCatalogChange', () => {
    expect(actions).toContainEqual(
      expect.objectContaining({
        type: 'QUERY_EDITOR_SET_CATALOG',
 +      catalog: 'new_catalog',
      }),
    );
  });
Citations

Code Review Run #09d82e


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Comment on lines +156 to +178
test('dispatches queryEditorSetSchema action on onSchemaChange', () => {
const store = mockStore(createInitialState());
const { result } = renderHook(
() => useDatabaseSelector(defaultQueryEditor.id),
{
wrapper: createWrapper({
useRedux: true,
store,
}),
},
);

act(() => {
result.current.onSchemaChange('new_schema');
});

const actions = store.getActions();
expect(actions).toContainEqual(
expect.objectContaining({
type: 'QUERY_EDITOR_SET_SCHEMA',
}),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Incomplete dispatch assertion

Test checks type but not payload.schema. Add expect.objectContaining({ schema: 'new_schema' }).

Code suggestion
Check the AI-generated fix before applying
 --- a/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 +++ b/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 @@ -173,6 +173,7 @@ test('dispatches queryEditorSetSchema action on onSchemaChange', () => {
    expect(actions).toContainEqual(
      expect.objectContaining({
        type: 'QUERY_EDITOR_SET_SCHEMA',
 +      schema: 'new_schema',
      }),
    );
  });
Citations

Code Review Run #09d82e


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Comment on lines +180 to +208
test('dispatches setDatabases action on getDbList', () => {
const store = mockStore(createInitialState());
const { result } = renderHook(
() => useDatabaseSelector(defaultQueryEditor.id),
{
wrapper: createWrapper({
useRedux: true,
store,
}),
},
);

const newDatabase = {
id: 3,
database_name: 'test_db',
backend: 'postgresql',
};

act(() => {
result.current.getDbList(newDatabase as any);
});

const actions = store.getActions();
expect(actions).toContainEqual(
expect.objectContaining({
type: 'SET_DATABASES',
}),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Type mismatch in getDbList test

Test passes single object to getDbList, but hook expects DatabaseObject[]. Change to [newDatabase] and assert payload.databases.

Code suggestion
Check the AI-generated fix before applying
 --- a/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 +++ b/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 @@ -192,7 +192,7 @@ test('dispatches setDatabases action on getDbList', () => {
    const newDatabase = {
      id: 3,
      database_name: 'test_db',
      backend: 'postgresql',
    };
 
    act(() => {
 -    result.current.getDbList(newDatabase as any);
 +    result.current.getDbList([newDatabase]);
    });
 
    const actions = store.getActions();
    expect(actions).toContainEqual(
      expect.objectContaining({
        type: 'SET_DATABASES',
 +      databases: [newDatabase],
      }),
    );
  });
Citations

Code Review Run #09d82e


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Comment on lines +298 to +320
test('handles null catalog change', () => {
const store = mockStore(createInitialState());
const { result } = renderHook(
() => useDatabaseSelector(defaultQueryEditor.id),
{
wrapper: createWrapper({
useRedux: true,
store,
}),
},
);

act(() => {
result.current.onCatalogChange(null);
});

const actions = store.getActions();
expect(actions).toContainEqual(
expect.objectContaining({
type: 'QUERY_EDITOR_SET_CATALOG',
}),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Incomplete dispatch assertion

Test checks type but not payload.catalog === null. Add to expect.objectContaining.

Code suggestion
Check the AI-generated fix before applying
 --- a/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 +++ b/superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
 @@ -315,6 +315,7 @@ test('handles null catalog change', () => {
    expect(actions).toContainEqual(
      expect.objectContaining({
        type: 'QUERY_EDITOR_SET_CATALOG',
 +      catalog: null,
      }),
    );
  });
Citations

Code Review Run #09d82e


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

@bito-code-review
Copy link
Contributor

bito-code-review bot commented Jan 7, 2026

Code Review Agent Run #9d6b54

Actionable Suggestions - 0
Additional Suggestions - 1
  • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx - 1
    • Unused import cleanup · Line 29-29
      The removal of the unused 'type Database' import is appropriate, as the Database type is not referenced anywhere in this file. This is a safe cleanup that reduces bundle size and improves code clarity.
Review Details
  • Files reviewed - 29 · Commit Range: c689c41..f5cc11b
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/EstimateQueryCostButton/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/RunQueryActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuExtension/index.tsx
    • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

@codeant-ai-for-open-source
Copy link
Contributor

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

Copy link
Contributor

@bito-code-review bito-code-review 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 Agent Run #edfa64

Actionable Suggestions - 1
  • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx - 1
Review Details
  • Files reviewed - 29 · Commit Range: f5cc11b..f6e1549
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/EstimateQueryCostButton/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/RunQueryActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/MenuExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuExtension/index.tsx
    • superset-frontend/src/components/ViewExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

Comment on lines +22 to +29
jest.mock('src/extensions/ExtensionsManager', () => {
const getInstance = jest.fn().mockReturnValue({
getViewContributions: jest
.fn()
.mockReturnValue([{ id: 'test-status-bar' }]),
});
return { getInstance };
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Jest Mock Missing __esModule

The Jest mock for the default export of ExtensionsManager is missing __esModule: true, which Jest requires for ES module mocking. Without it, the import may not resolve correctly, potentially causing test failures. Other mocks in the codebase, like ViewExtension, include this property.

Code suggestion
Check the AI-generated fix before applying
Suggested change
jest.mock('src/extensions/ExtensionsManager', () => {
const getInstance = jest.fn().mockReturnValue({
getViewContributions: jest
.fn()
.mockReturnValue([{ id: 'test-status-bar' }]),
});
return { getInstance };
});
jest.mock('src/extensions/ExtensionsManager', () => {
const getInstance = jest.fn().mockReturnValue({
getViewContributions: jest
.fn()
.mockReturnValue([{ id: 'test-status-bar' }]),
});
return { __esModule: true, getInstance };
});

Code Review Run #edfa64


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

@kasiazjc
Copy link
Contributor

kasiazjc commented Jan 8, 2026

Thank you for the latest changes @justinpark. I have some design suggestions that could be addressed in follow-up PRs but I think it would be easier to do them in this PR so that @kasiazjc can review the final form of the screen.

Screenshot 2026-01-05 at 11 10 42 1. I think the tabs and buttons are a little too big and taking more vertical space than needed. My suggestion would be to use a smaller size to all. 2. The vertical blank space in the editor, reserved for the line numbers, is a little confusing given that we're using the white/grey contrast to separate part of the screen. My suggestion would use the same background as the rest of the editor and add a separator. 3. The editor's handle to drag has a darker background when comparing with the editor's background, creating the illusion of a border. I would use the same background color. 4. Given that the editor is grey, I would use a white background for the panels to give more contrast.

Something like this:

Screenshot 2026-01-05 at 11 51 10 @kasiazjc These are just suggestions and I bet you can get to something even better.

@justinpark @michael-s-molina thank you for all the work and changes you did!

I think moving the buttons to the left (and adding the text to the primary) make sense. Had to do a little bit of digging to confirm that this is also a pattern that is used, so if that's the case - I am on board :)

Some quicks notes on the things I noticed in the screenshots below!

Buttons for secondary actions

I think looking at it now, the number of different highlighted buttons/components seem a bit overwhelming - especially the number of secondary actions. Icons also have different colors, which adds to the inconsistency.

image

What do you think about changing the secondary action buttons to just icons/dropdown triggers (possibly with dividers)? I think in ant design they are called ghost buttons. Found this example in JetBrains and I really like the clean look. I would still keep run as primary action though.

image

SQL Area

So in here I will be honest - I am not a fan of the gray background for the main/central areas, as not only it can cause accessibility problems, but also it seems outdated. I know I myself put it in here myself, but in the screenshots it seems darker than designs which I think is a problem - so updated proposal below. I would suggest going with a clean, minimalist look, which would be a white background. Was trying to see what some other tools are doing and it's like half and half (white or gray).

So basically:

  • white background
  • separator at the top and a little bit more breathing space between buttons and sql area (seems squished right now)
  • separator at the bottom

This would also help with seeing which row is actually being highlighted as currently it blends with the gray background.

image

Top tabs

Making them smaller - makes sense to me

Tabs for results etc

With the gray that is being used for the background (which I didn't consider before, sorry about that) it seems like the tabs are "under" the content, or indented in a way. I would again do white background and a little bit more padding at the top. I know that in general we want to have as much items etc as possible, but with this number of actions it starts to get crowded.

image

I think that is all for now, let me know what you think! I am open for discussion 😌

@michael-s-molina
Copy link
Member

@kasiazjc I love the proposed changes!

I also have a big problem with grey, extra borders, or things that decrease visual clarity. I really prefer a clean look, specially in SQL Lab given that we have so many features available.

@justinpark
Copy link
Member Author

Updated design:

Screenshot 2026-01-08 at 6 08 28 PM

@codeant-ai-for-open-source
Copy link
Contributor

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

Copy link
Contributor

@bito-code-review bito-code-review 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 Agent Run #dd9e59

Actionable Suggestions - 1
  • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx - 1
Additional Suggestions - 7
  • superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx - 2
    • Remove debug console.log · Line 154-154
      This console.log appears to be debug code for logging cursor position during editor load. It should be removed before merging to avoid cluttering production console output.
      Code suggestion
      --- a/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
      +++ b/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
       @@ -152,7 +152,6 @@
            // setTimeout(() => {
            const { row, column } = cursorPosition;
      -    console.log('moving cursor to', { row, column });
            editor.moveCursorToPosition({ row, column });
            editor.focus();
            editor.scrollToLine(row, true, true);
            // }, 100);
    • Custom CSS addition · Line 195-214
      The added CSS styles for Ace Editor theming use antd tokens, which is good, but the AGENTS.md guidelines recommend avoiding custom CSS whenever possible. Since this is for a third-party component (Ace Editor), it may be necessary, but verify if Ace's theme configuration can achieve the same result.
  • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx - 1
    • Unconditional UI dividers · Line 51-57
      The dividers are rendered unconditionally, which may show extra separators if defaultSecondaryActions is empty (since MenuListExtension returns null in that case). Consider checking `defaultSecondaryActions?.length > 0` before rendering the divider, secondary component, and final divider to avoid UI clutter.
  • superset-frontend/src/SqlLab/components/EstimateQueryCostButton/index.tsx - 4
    • Unused prop removal · Line 40-40
      The removal of the unused compactMode prop from the interface cleans up the code without affecting functionality, as it was not passed in any usage.
    • Unused parameter removal · Line 54-54
      Removing the unused compactMode parameter from the function signature maintains the same behavior, as the default was false and no callers passed it.
    • API modernization · Line 115-117
      Updating Button props from custom buttonStyle to Antd's native color and variant aligns with modernization guidelines, as verified in Antd 5.26 docs.
    • Conditional cleanup · Line 126-126
      Removing the conditional rendering of btnText, as compactMode was removed and defaulted to false, ensures text is always shown without changing behavior.
Review Details
  • Files reviewed - 31 · Commit Range: f6e1549..a5b30ad
    • superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
    • superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx
    • superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
    • superset-frontend/src/SqlLab/components/AppLayout/index.tsx
    • superset-frontend/src/SqlLab/components/EstimateQueryCostButton/EstimateQueryCostButton.test.tsx
    • superset-frontend/src/SqlLab/components/EstimateQueryCostButton/index.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/QueryLimitSelect.test.tsx
    • superset-frontend/src/SqlLab/components/QueryLimitSelect/index.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/RunQueryActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/SaveDatasetActionButton.test.tsx
    • superset-frontend/src/SqlLab/components/SaveDatasetActionButton/index.tsx
    • superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
    • superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
    • superset-frontend/src/SqlLab/components/SouthPane/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorLeftBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/SqlEditorTopBar.test.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/index.tsx
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.test.ts
    • superset-frontend/src/SqlLab/components/SqlEditorTopBar/useDatabaseSelector.ts
    • superset-frontend/src/SqlLab/components/StatusBar/StatusBar.test.tsx
    • superset-frontend/src/SqlLab/components/StatusBar/index.tsx
    • superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
    • superset-frontend/src/SqlLab/constants.ts
    • superset-frontend/src/SqlLab/contributions.ts
    • superset-frontend/src/components/MenuListExtension/MenuExtension.test.tsx
    • superset-frontend/src/components/MenuListExtension/index.tsx
    • superset-frontend/src/components/ViewListExtension/ViewExtension.test.tsx
    • superset-frontend/src/components/ViewListExtension/index.tsx
  • Files skipped - 0
  • Tools
    • Eslint (Linter) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at [email protected].

Documentation & Help

AI Code Review powered by Bito Logo

display: flex;
margin: 0;
color: ${({ theme }) => theme.colorIcon};
svg {
Copy link
Contributor

Choose a reason for hiding this comment

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

Icon color styling issue

The removal of the color property from the span may cause icons in the save query modal to lose their theme-based color, potentially making them invisible or incorrectly colored. Based on similar patterns in the codebase, the color should be applied to the svg element instead.

Citations

Code Review Run #dd9e59


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:frontend Requires changing the frontend packages review:draft size/XXL size:XXL This PR changes 1000+ lines, ignoring generated files sqllab Namespace | Anything related to the SQL Lab

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

4 participants