feat(sqllab): Show sql in the current result (#24787)

This commit is contained in:
JUST.in DO IT 2023-09-06 09:48:42 -07:00 committed by GitHub
parent a40e9a4d06
commit 2d4de5146b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 15 deletions

View File

@ -25,7 +25,7 @@ import ModalTrigger from 'src/components/ModalTrigger';
SyntaxHighlighter.registerLanguage('sql', sql); SyntaxHighlighter.registerLanguage('sql', sql);
interface HighlightedSqlProps { export interface HighlightedSqlProps {
sql: string; sql: string;
rawSql?: string; rawSql?: string;
maxWidth?: number; maxWidth?: number;

View File

@ -27,8 +27,11 @@ import {
QueryState, QueryState,
styled, styled,
t, t,
tn,
useTheme, useTheme,
usePrevious, usePrevious,
css,
getNumberFormatter,
} from '@superset-ui/core'; } from '@superset-ui/core';
import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace'; import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
import { import {
@ -42,6 +45,9 @@ import { mountExploreUrl } from 'src/explore/exploreUtils';
import { postFormData } from 'src/explore/exploreUtils/formData'; import { postFormData } from 'src/explore/exploreUtils/formData';
import ProgressBar from 'src/components/ProgressBar'; import ProgressBar from 'src/components/ProgressBar';
import Loading from 'src/components/Loading'; import Loading from 'src/components/Loading';
import Card from 'src/components/Card';
import Label from 'src/components/Label';
import { Tooltip } from 'src/components/Tooltip';
import FilterableTable from 'src/components/FilterableTable'; import FilterableTable from 'src/components/FilterableTable';
import CopyToClipboard from 'src/components/CopyToClipboard'; import CopyToClipboard from 'src/components/CopyToClipboard';
import { addDangerToast } from 'src/components/MessageToasts/actions'; import { addDangerToast } from 'src/components/MessageToasts/actions';
@ -55,6 +61,7 @@ import {
reRunQuery, reRunQuery,
} from 'src/SqlLab/actions/sqlLab'; } from 'src/SqlLab/actions/sqlLab';
import { URL_PARAMS } from 'src/constants'; import { URL_PARAMS } from 'src/constants';
import Icons from 'src/components/Icons';
import ExploreCtasResultsButton from '../ExploreCtasResultsButton'; import ExploreCtasResultsButton from '../ExploreCtasResultsButton';
import ExploreResultsButton from '../ExploreResultsButton'; import ExploreResultsButton from '../ExploreResultsButton';
import HighlightedSql from '../HighlightedSql'; import HighlightedSql from '../HighlightedSql';
@ -76,6 +83,7 @@ export interface ResultSetProps {
query: QueryResponse; query: QueryResponse;
search?: boolean; search?: boolean;
showSql?: boolean; showSql?: boolean;
showSqlInline?: boolean;
visualize?: boolean; visualize?: boolean;
user: UserWithPermissionsAndRoles; user: UserWithPermissionsAndRoles;
defaultQueryLimit: number; defaultQueryLimit: number;
@ -110,7 +118,7 @@ const MonospaceDiv = styled.div`
const ReturnedRows = styled.div` const ReturnedRows = styled.div`
font-size: ${({ theme }) => theme.typography.sizes.s}px; font-size: ${({ theme }) => theme.typography.sizes.s}px;
line-height: ${({ theme }) => theme.gridUnit * 6}px; line-height: 1;
`; `;
const ResultSetControls = styled.div` const ResultSetControls = styled.div`
@ -124,10 +132,8 @@ const ResultSetButtons = styled.div`
padding-right: ${({ theme }) => 2 * theme.gridUnit}px; padding-right: ${({ theme }) => 2 * theme.gridUnit}px;
`; `;
const LimitMessage = styled.span` const ROWS_CHIP_WIDTH = 100;
color: ${({ theme }) => theme.colors.secondary.light1}; const GAP = 8;
margin-left: ${({ theme }) => theme.gridUnit * 2}px;
`;
const ResultSet = ({ const ResultSet = ({
cache = false, cache = false,
@ -138,6 +144,7 @@ const ResultSet = ({
query, query,
search = true, search = true,
showSql = false, showSql = false,
showSqlInline = false,
visualize = true, visualize = true,
user, user,
defaultQueryLimit, defaultQueryLimit,
@ -296,7 +303,7 @@ const ResultSet = ({
const renderRowsReturned = () => { const renderRowsReturned = () => {
const { results, rows, queryLimit, limitingFactor } = query; const { results, rows, queryLimit, limitingFactor } = query;
let limitMessage; let limitMessage = '';
const limitReached = results?.displayLimitReached; const limitReached = results?.displayLimitReached;
const limit = queryLimit || results.query.limit; const limit = queryLimit || results.query.limit;
const isAdmin = !!user?.roles?.Admin; const isAdmin = !!user?.roles?.Admin;
@ -339,7 +346,7 @@ const ResultSet = ({
{ rows }, { rows },
); );
} }
const formattedRowCount = getNumberFormatter()(rows);
const rowsReturnedMessage = t('%(rows)d rows returned', { const rowsReturnedMessage = t('%(rows)d rows returned', {
rows, rows,
}); });
@ -349,10 +356,27 @@ const ResultSet = ({
return ( return (
<ReturnedRows> <ReturnedRows>
{!limitReached && !shouldUseDefaultDropdownAlert && ( {!limitReached && !shouldUseDefaultDropdownAlert && (
<span title={tooltipText}> <Tooltip
{rowsReturnedMessage} id="sqllab-rowcount-tooltip"
<LimitMessage>{limitMessage}</LimitMessage> title={tooltipText}
</span> placement="left"
>
<Label
css={css`
line-height: ${theme.typography.sizes.l}px;
`}
>
{limitMessage && (
<Icons.ExclamationCircleOutlined
css={css`
font-size: ${theme.typography.sizes.m}px;
margin-right: ${theme.gridUnit}px;
`}
/>
)}
{tn('%s row', '%s rows', rows, formattedRowCount)}
</Label>
</Tooltip>
)} )}
{!limitReached && shouldUseDefaultDropdownAlert && ( {!limitReached && shouldUseDefaultDropdownAlert && (
<div ref={calculateAlertRefHeight}> <div ref={calculateAlertRefHeight}>
@ -413,7 +437,12 @@ const ResultSet = ({
} }
if (showSql) { if (showSql) {
sql = <HighlightedSql sql={query.sql} />; sql = (
<HighlightedSql
sql={query.sql}
{...(showSqlInline && { maxLines: 1, maxWidth: 60 })}
/>
);
} }
if (query.state === QueryState.STOPPED) { if (query.state === QueryState.STOPPED) {
@ -501,8 +530,39 @@ const ResultSet = ({
return ( return (
<ResultContainer> <ResultContainer>
{renderControls()} {renderControls()}
{renderRowsReturned()} {showSql && showSqlInline ? (
{sql} <div
css={css`
display: flex;
justify-content: space-between;
gap: ${GAP}px;
`}
>
<Card
css={[
css`
height: 28px;
width: calc(100% - ${ROWS_CHIP_WIDTH + GAP}px);
code {
width: 100%;
overflow: hidden;
white-space: nowrap !important;
text-overflow: ellipsis;
display: block;
}
`,
]}
>
{sql}
</Card>
{renderRowsReturned()}
</div>
) : (
<>
{renderRowsReturned()}
{sql}
</>
)}
<FilterableTable <FilterableTable
data={data} data={data}
orderedColumnKeys={results.columns.map(col => col.column_name)} orderedColumnKeys={results.columns.map(col => col.column_name)}

View File

@ -189,6 +189,8 @@ const SouthPane = ({
database={databases[latestQuery.dbId]} database={databases[latestQuery.dbId]}
displayLimit={displayLimit} displayLimit={displayLimit}
defaultQueryLimit={defaultQueryLimit} defaultQueryLimit={defaultQueryLimit}
showSql
showSqlInline
/> />
); );
} }