mirror of
https://github.com/apache/superset.git
synced 2026-06-01 13:49:21 +00:00
fix: Query history view button in SqlLab (#36540)
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { useMemo, ReactNode } from 'react';
|
||||
import { useMemo, ReactNode, useState, useRef } from 'react';
|
||||
import {
|
||||
Card,
|
||||
Button,
|
||||
@@ -27,9 +27,9 @@ import {
|
||||
TableView,
|
||||
} from '@superset-ui/core/components';
|
||||
import ProgressBar from '@superset-ui/core/components/ProgressBar';
|
||||
import { t, QueryResponse } from '@superset-ui/core';
|
||||
import { t, QueryResponse, QueryState } from '@superset-ui/core';
|
||||
import { useTheme } from '@apache-superset/core/ui';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import {
|
||||
queryEditorSetSql,
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
fetchQueryResults,
|
||||
clearQueryResults,
|
||||
removeQuery,
|
||||
startQuery,
|
||||
} from 'src/SqlLab/actions/sqlLab';
|
||||
import { fDuration, extendedDayjs } from '@superset-ui/core/utils/dates';
|
||||
import { SqlLabRootState } from 'src/SqlLab/types';
|
||||
@@ -44,7 +45,7 @@ import { UserWithPermissionsAndRoles as User } from 'src/types/bootstrapTypes';
|
||||
import { makeUrl } from 'src/utils/pathUtils';
|
||||
import ResultSet from '../ResultSet';
|
||||
import HighlightedSql from '../HighlightedSql';
|
||||
import { StaticPosition, StyledTooltip } from './styles';
|
||||
import { StaticPosition, StyledTooltip, ModalResultSetWrapper } from './styles';
|
||||
|
||||
interface QueryTableQuery extends Omit<
|
||||
QueryResponse,
|
||||
@@ -82,6 +83,15 @@ const QueryTable = ({
|
||||
}: QueryTableProps) => {
|
||||
const theme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const [selectedQuery, setSelectedQuery] = useState<QueryResponse | null>(
|
||||
null,
|
||||
);
|
||||
const selectedQueryRef = useRef<QueryResponse | null>(null);
|
||||
const modalRef = useRef<{
|
||||
close: () => void;
|
||||
open: (e: React.MouseEvent) => void;
|
||||
showModal: boolean;
|
||||
} | null>(null);
|
||||
|
||||
const QUERY_HISTORY_TABLE_HEADERS_LOCALIZED = {
|
||||
state: t('State'),
|
||||
@@ -116,6 +126,14 @@ const QueryTable = ({
|
||||
);
|
||||
|
||||
const user = useSelector<SqlLabRootState, User>(state => state.user);
|
||||
const reduxQueries = useSelector<
|
||||
SqlLabRootState,
|
||||
Record<string, QueryResponse>
|
||||
>(state => state.sqlLab?.queries ?? {}, shallowEqual);
|
||||
|
||||
const openAsyncResults = (query: QueryResponse, displayLimit: number) => {
|
||||
dispatch(fetchQueryResults(query, displayLimit));
|
||||
};
|
||||
|
||||
const data = useMemo(() => {
|
||||
const restoreSql = (query: QueryResponse) => {
|
||||
@@ -128,10 +146,6 @@ const QueryTable = ({
|
||||
dispatch(cloneQueryToNewTab(query, true));
|
||||
};
|
||||
|
||||
const openAsyncResults = (query: QueryResponse, displayLimit: number) => {
|
||||
dispatch(fetchQueryResults(query, displayLimit));
|
||||
};
|
||||
|
||||
const statusAttributes = {
|
||||
success: {
|
||||
config: {
|
||||
@@ -289,26 +303,17 @@ const QueryTable = ({
|
||||
);
|
||||
if (q.resultsKey) {
|
||||
q.results = (
|
||||
<ModalTrigger
|
||||
className="ResultsModal"
|
||||
triggerNode={
|
||||
<Button buttonSize="xsmall" buttonStyle="secondary">
|
||||
{t('View')}
|
||||
</Button>
|
||||
}
|
||||
modalTitle={t('Data preview')}
|
||||
beforeOpen={() => openAsyncResults(query, displayLimit)}
|
||||
onExit={() => dispatch(clearQueryResults(query))}
|
||||
modalBody={
|
||||
<ResultSet
|
||||
showSql
|
||||
queryId={query.id}
|
||||
displayLimit={displayLimit}
|
||||
defaultQueryLimit={1000}
|
||||
/>
|
||||
}
|
||||
responsive
|
||||
/>
|
||||
<Button
|
||||
buttonSize="xsmall"
|
||||
buttonStyle="secondary"
|
||||
onClick={(e: React.MouseEvent) => {
|
||||
selectedQueryRef.current = query;
|
||||
setSelectedQuery(query);
|
||||
modalRef.current?.open(e);
|
||||
}}
|
||||
>
|
||||
{t('View')}
|
||||
</Button>
|
||||
);
|
||||
} else {
|
||||
q.results = <></>;
|
||||
@@ -365,6 +370,55 @@ const QueryTable = ({
|
||||
|
||||
return (
|
||||
<div className="QueryTable">
|
||||
<ModalTrigger
|
||||
ref={modalRef}
|
||||
triggerNode={null}
|
||||
className="ResultsModal"
|
||||
modalTitle={t('Data preview')}
|
||||
beforeOpen={() => {
|
||||
const query = selectedQueryRef.current;
|
||||
if (query) {
|
||||
const existingQuery = reduxQueries[query.id];
|
||||
if (!existingQuery?.sql && query.sql) {
|
||||
dispatch(startQuery({ ...query, sql: query.sql }, false));
|
||||
}
|
||||
openAsyncResults(query, displayLimit);
|
||||
}
|
||||
}}
|
||||
onExit={() => {
|
||||
const query = selectedQueryRef.current;
|
||||
if (query) {
|
||||
dispatch(clearQueryResults(query));
|
||||
selectedQueryRef.current = null;
|
||||
setSelectedQuery(null);
|
||||
}
|
||||
}}
|
||||
modalBody={
|
||||
selectedQuery ? (
|
||||
<ModalResultSetWrapper>
|
||||
{(() => {
|
||||
const height =
|
||||
reduxQueries[selectedQuery.id]?.state ===
|
||||
QueryState.Success &&
|
||||
reduxQueries[selectedQuery.id]?.results
|
||||
? Math.floor(window.innerHeight * 0.5)
|
||||
: undefined;
|
||||
return (
|
||||
<ResultSet
|
||||
showSql
|
||||
queryId={selectedQuery.id}
|
||||
displayLimit={displayLimit}
|
||||
defaultQueryLimit={1000}
|
||||
useFixedHeight
|
||||
height={height}
|
||||
/>
|
||||
);
|
||||
})()}
|
||||
</ModalResultSetWrapper>
|
||||
) : null
|
||||
}
|
||||
responsive
|
||||
/>
|
||||
<TableView
|
||||
columns={columnsOfTable}
|
||||
data={data}
|
||||
|
||||
Reference in New Issue
Block a user