fix(SqlLab): improve SQL diff modal — responsive width, padding, tabs, and copy button (#39246)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
(cherry picked from commit 450701ecec)
This commit is contained in:
Maxime Beauchemin
2026-04-10 12:11:05 -07:00
committed by Michael S. Molina
parent 0d5c7cb9b0
commit 1d9dbe0697
8 changed files with 306 additions and 121 deletions

View File

@@ -36,13 +36,40 @@ test('renders a ModalTrigger component with shrink prop and maxWidth prop set to
);
expect(getByTestId('span-modal-trigger')).toBeInTheDocument();
});
test('renders two code elements in modal when rawSql prop is provided', () => {
const { getByRole, queryByRole, getByTestId } = render(
<HighlightedSql sql={sql} rawSql="SELECT * FORM foo" shrink maxWidth={5} />,
test('renders single SQL block with no tabs when rawSql equals sql', () => {
const { queryByRole, getByTestId, queryByText } = render(
<HighlightedSql sql={sql} rawSql={sql} shrink maxWidth={5} />,
);
expect(queryByRole('dialog')).not.toBeInTheDocument();
fireEvent.click(getByTestId('span-modal-trigger'));
expect(queryByRole('dialog')).toBeInTheDocument();
const codeElements = getByRole('dialog').getElementsByTagName('code');
expect(codeElements.length).toEqual(2);
expect(queryByText('Executed SQL')).not.toBeInTheDocument();
expect(queryByText('Source SQL')).toBeInTheDocument();
});
test('renders tabs when rawSql differs from sql', () => {
const { queryByRole, getByTestId, getByText } = render(
<HighlightedSql sql={sql} rawSql="SELECT * FROM foo" shrink maxWidth={5} />,
);
expect(queryByRole('dialog')).not.toBeInTheDocument();
fireEvent.click(getByTestId('span-modal-trigger'));
expect(queryByRole('dialog')).toBeInTheDocument();
expect(getByText('Executed SQL')).toBeInTheDocument();
expect(getByText('Source SQL')).toBeInTheDocument();
});
test('renders tabs when rawSql has an added LIMIT', () => {
const { queryByRole, getByTestId, getByText } = render(
<HighlightedSql
sql={sql}
rawSql={`${sql} LIMIT 1000`}
shrink
maxWidth={5}
/>,
);
expect(queryByRole('dialog')).not.toBeInTheDocument();
fireEvent.click(getByTestId('span-modal-trigger'));
expect(queryByRole('dialog')).toBeInTheDocument();
expect(getByText('Executed SQL')).toBeInTheDocument();
expect(getByText('Source SQL')).toBeInTheDocument();
});

View File

@@ -16,9 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
import { css, styled, useTheme } from '@apache-superset/core/theme';
import { styled, useTheme } from '@apache-superset/core/theme';
import { t } from '@apache-superset/core/translation';
import { ModalTrigger } from '@superset-ui/core/components';
import { ModalTrigger, Tabs } from '@superset-ui/core/components';
import CodeSyntaxHighlighter from '@superset-ui/core/components/CodeSyntaxHighlighter';
export interface HighlightedSqlProps {
@@ -63,7 +63,7 @@ const shrinkSql = (sql: string, maxLines: number, maxWidth: number) => {
function TriggerNode({ shrink, sql, maxLines, maxWidth }: TriggerNodeProps) {
return (
<CodeSyntaxHighlighter language="sql">
<CodeSyntaxHighlighter language="sql" showCopyButton={false}>
{shrink ? shrinkSql(sql, maxLines, maxWidth) : sql}
</CodeSyntaxHighlighter>
);
@@ -80,25 +80,43 @@ function HighlightSqlModal({ rawSql, sql }: HighlightedSqlModalTypes) {
padding: theme.sizeUnit * 2,
};
const isDifferent = !!rawSql && rawSql !== sql;
if (!isDifferent) {
return (
<div>
<Title>{t('Source SQL')}</Title>
<CodeSyntaxHighlighter language="sql" customStyle={codeBlockStyle}>
{sql}
</CodeSyntaxHighlighter>
</div>
);
}
return (
<div
css={css`
margin: -${theme.sizeUnit * 6}px;
`}
>
<Title>{t('Source SQL')}</Title>
<CodeSyntaxHighlighter language="sql" customStyle={codeBlockStyle}>
{sql}
</CodeSyntaxHighlighter>
{rawSql && rawSql !== sql && (
<div>
<Title>{t('Executed SQL')}</Title>
<CodeSyntaxHighlighter language="sql" customStyle={codeBlockStyle}>
{rawSql}
</CodeSyntaxHighlighter>
</div>
)}
</div>
<Tabs
defaultActiveKey="executed"
items={[
{
key: 'executed',
label: t('Executed SQL'),
children: (
<CodeSyntaxHighlighter language="sql" customStyle={codeBlockStyle}>
{rawSql!}
</CodeSyntaxHighlighter>
),
},
{
key: 'source',
label: t('Source SQL'),
children: (
<CodeSyntaxHighlighter language="sql" customStyle={codeBlockStyle}>
{sql}
</CodeSyntaxHighlighter>
),
},
]}
/>
);
}
@@ -121,6 +139,7 @@ function HighlightedSql({
maxWidth={maxWidth}
/>
}
responsive
/>
);
}