This is an automated email from the ASF dual-hosted git repository.

asoare pushed a commit to branch alexandrusoare/fix/custom-sql-tab
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 0f26cd3633c32a64e4fdc4d88ff3294f14875748
Author: alexandrusoare <[email protected]>
AuthorDate: Wed Feb 25 15:31:17 2026 +0200

    fix(bug): fix custom sql issue
---
 .../packages/superset-core/src/api/editors.ts      |  8 +++
 .../src/core/editors/AceEditorProvider.tsx         |  4 ++
 .../AdhocFilterEditPopoverSqlTabContent.test.tsx   | 81 ++++++++++++++++++----
 .../AdhocFilterEditPopoverSqlTabContent/index.tsx  |  8 +--
 4 files changed, 85 insertions(+), 16 deletions(-)

diff --git a/superset-frontend/packages/superset-core/src/api/editors.ts 
b/superset-frontend/packages/superset-core/src/api/editors.ts
index cc57dde3073..4484bdecc52 100644
--- a/superset-frontend/packages/superset-core/src/api/editors.ts
+++ b/superset-frontend/packages/superset-core/src/api/editors.ts
@@ -457,6 +457,14 @@ export interface EditorHandle {
    * @returns A Disposable that removes the provider when disposed
    */
   registerCompletionProvider(provider: CompletionProvider): Disposable;
+
+  /**
+   * Force the editor to recalculate its dimensions.
+   * Optional - not all editors need this (some auto-resize via CSS).
+   * Useful when the editor container size changes or when the editor
+   * becomes visible after being hidden (e.g., in a tab).
+   */
+  resize?(): void;
 }
 
 /**
diff --git a/superset-frontend/src/core/editors/AceEditorProvider.tsx 
b/superset-frontend/src/core/editors/AceEditorProvider.tsx
index 89c8a579117..1cbbead5c9f 100644
--- a/superset-frontend/src/core/editors/AceEditorProvider.tsx
+++ b/superset-frontend/src/core/editors/AceEditorProvider.tsx
@@ -179,6 +179,10 @@ const createAceEditorHandle = (
       completionProviders.current.delete(provider.id);
     });
   },
+
+  resize: () => {
+    aceEditorRef.current?.editor?.resize();
+  },
 });
 
 /**
diff --git 
a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/AdhocFilterEditPopoverSqlTabContent.test.tsx
 
b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/AdhocFilterEditPopoverSqlTabContent.test.tsx
index 2a29116e118..8115195d11f 100644
--- 
a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/AdhocFilterEditPopoverSqlTabContent.test.tsx
+++ 
b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/AdhocFilterEditPopoverSqlTabContent.test.tsx
@@ -27,25 +27,46 @@ import AdhocFilter from '../AdhocFilter';
 import { Clauses, ExpressionTypes } from '../types';
 import AdhocFilterEditPopoverSqlTabContent from '.';
 
+// Track resize calls for testing
+const mockResize = jest.fn();
+
+// Mock EditorHost with ref support for resize
+jest.mock('src/core/editors', () => {
+  const React = require('react');
+  return {
+    EditorHost: React.forwardRef(
+      (
+        {
+          value,
+          onChange,
+        }: {
+          value: string;
+          onChange: (v: string) => void;
+        },
+        ref: React.Ref<{ resize: () => void }>,
+      ) => {
+        React.useImperativeHandle(ref, () => ({
+          resize: mockResize,
+        }));
+        return (
+          <textarea
+            defaultValue={value}
+            onChange={e => onChange?.(e.target.value)}
+          />
+        );
+      },
+    ),
+  };
+});
+
 // Add cleanup after each test
 afterEach(async () => {
   cleanup();
+  mockResize.mockClear();
   // Wait for any pending effects to complete
   await new Promise(resolve => setTimeout(resolve, 0));
 });
 
-jest.mock('src/core/editors', () => ({
-  EditorHost: ({
-    value,
-    onChange,
-  }: {
-    value: string;
-    onChange: (v: string) => void;
-  }) => (
-    <textarea defaultValue={value} onChange={e => onChange?.(e.target.value)} 
/>
-  ),
-}));
-
 const adhocFilter = new AdhocFilter({
   expressionType: ExpressionTypes.Sql,
   sqlExpression: 'value > 10',
@@ -89,3 +110,39 @@ test('calls onChange when the SQL expression changes', 
async () => {
     expect.objectContaining({ sqlExpression: input }),
   );
 });
+
+test('calls editor resize when adhocFilter changes', async () => {
+  const onChange = jest.fn();
+  const { rerender } = render(
+    <AdhocFilterEditPopoverSqlTabContent
+      adhocFilter={adhocFilter}
+      onChange={onChange}
+      options={[]}
+      height={100}
+    />,
+  );
+
+  // Initial render should call resize
+  await new Promise(resolve => setTimeout(resolve, 0));
+  expect(mockResize).toHaveBeenCalled();
+  mockResize.mockClear();
+
+  // Create a new filter to trigger the useEffect
+  const newFilter = new AdhocFilter({
+    expressionType: ExpressionTypes.Sql,
+    sqlExpression: 'value > 20',
+    clause: Clauses.Where,
+  });
+
+  rerender(
+    <AdhocFilterEditPopoverSqlTabContent
+      adhocFilter={newFilter}
+      onChange={onChange}
+      options={[]}
+      height={100}
+    />,
+  );
+
+  await new Promise(resolve => setTimeout(resolve, 0));
+  expect(mockResize).toHaveBeenCalled();
+});
diff --git 
a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.tsx
 
b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.tsx
index 9ba11c617e0..d23d562b138 100644
--- 
a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.tsx
+++ 
b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent/index.tsx
@@ -17,6 +17,7 @@
  * under the License.
  */
 import { useEffect, useRef, useMemo } from 'react';
+import type { editors } from '@apache-superset/core';
 import { Select } from '@superset-ui/core/components';
 import { t } from '@apache-superset/core';
 import { css, styled, useTheme } from '@apache-superset/core/ui';
@@ -49,12 +50,11 @@ export default function 
AdhocFilterEditPopoverSqlTabContent({
   height: number;
   datasource?: any;
 }) {
-  const aceEditorRef = useRef(null);
+  const editorRef = useRef<editors.EditorHandle>(null);
   const theme = useTheme();
 
   useEffect(() => {
-    // @ts-expect-error - AceEditor ref type doesn't expose editor.resize()
-    aceEditorRef?.current?.editor.resize();
+    editorRef.current?.resize?.();
   }, [adhocFilter]);
 
   const onSqlExpressionClauseChange = (clause: string) => {
@@ -125,7 +125,7 @@ export default function 
AdhocFilterEditPopoverSqlTabContent({
         `}
       >
         <SQLEditorWithValidation
-          ref={aceEditorRef}
+          ref={editorRef}
           keywords={keywords}
           height={`${height - 130}px`}
           onChange={onSqlExpressionChange}

Reply via email to