fix(sqllab): Invisible grid table due to the invalid height (#34683)

This commit is contained in:
JUST.in DO IT
2025-08-19 10:09:39 -07:00
committed by GitHub
parent f99022b242
commit 89eb7b207c
4 changed files with 40 additions and 58 deletions

View File

@@ -16,6 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { type ReactChild } from 'react';
import {
render,
screen,
@@ -45,6 +46,13 @@ jest.mock('src/components/ErrorMessage', () => ({
ErrorMessageWithStackTrace: () => <div data-test="error-message">Error</div>,
}));
jest.mock(
'react-virtualized-auto-sizer',
() =>
({ children }: { children: (params: { height: number }) => ReactChild }) =>
children({ height: 500 }),
);
const mockedProps = {
cache: true,
queryId: queries[0].id,

View File

@@ -25,6 +25,7 @@ import {
MouseEvent,
} from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { pick } from 'lodash';
@@ -116,6 +117,7 @@ const ResultContainer = styled.div`
display: flex;
flex-direction: column;
row-gap: ${({ theme }) => theme.sizeUnit * 2}px;
height: 100%;
`;
const ResultlessStyles = styled.div`
@@ -221,7 +223,6 @@ const ResultSet = ({
const [searchText, setSearchText] = useState('');
const [cachedData, setCachedData] = useState<Record<string, unknown>[]>([]);
const [showSaveDatasetModal, setShowSaveDatasetModal] = useState(false);
const [alertIsOpen, setAlertIsOpen] = useState(false);
const history = useHistory();
const dispatch = useDispatch();
@@ -256,14 +257,6 @@ const ResultSet = ({
}
}, [query, cache]);
const calculateAlertRefHeight = (alertElement: HTMLElement | null) => {
if (alertElement) {
setAlertIsOpen(true);
} else {
setAlertIsOpen(false);
}
};
const popSelectStar = (tempSchema: string | null, tempTable: string) => {
const qe = {
id: nanoid(11),
@@ -471,10 +464,10 @@ const ResultSet = ({
return (
<>
{!limitReached && shouldUseDefaultDropdownAlert && (
<div ref={calculateAlertRefHeight}>
<div>
<Alert
closable
type="warning"
onClose={() => setAlertIsOpen(false)}
message={t(
'The number of rows displayed is limited to %(rows)d by the dropdown.',
{ rows },
@@ -483,10 +476,10 @@ const ResultSet = ({
</div>
)}
{limitReached && (
<div ref={calculateAlertRefHeight}>
<div>
<Alert
closable
type="warning"
onClose={() => setAlertIsOpen(false)}
message={
isAdmin
? displayMaxRowsReachedMessage.withAdmin
@@ -532,7 +525,6 @@ const ResultSet = ({
);
};
const limitReached = query?.results?.displayLimitReached;
let sql;
let exploreDBId = query.dbId;
if (database?.explore_database_id) {
@@ -646,17 +638,6 @@ const ResultSet = ({
if (query.state === QueryState.Success && query.results) {
const { results } = query;
// Accounts for offset needed for height of ResultSetRowsReturned component if !limitReached
const rowMessageHeight = !limitReached ? 32 : 0;
// Accounts for offset needed for height of Alert if this.state.alertIsOpen
const alertContainerHeight = 70;
// We need to calculate the height of this.renderRowsReturned()
// if we want results panel to be proper height because the
// FilterTable component needs an explicit height to render
// the Table component
const rowsHeight = alertIsOpen
? height - alertContainerHeight
: height - rowMessageHeight;
let data;
if (cache && query.cached) {
data = cachedData;
@@ -712,15 +693,27 @@ const ResultSet = ({
{sql}
</>
)}
<ResultTable
data={data}
queryId={query.id}
orderedColumnKeys={results.columns.map(col => col.column_name)}
height={rowsHeight}
filterText={searchText}
expandedColumns={expandedColumns}
allowHTML={allowHTML}
/>
<div
css={css`
flex: 1 1 auto;
`}
>
<AutoSizer disableWidth>
{({ height }) => (
<ResultTable
data={data}
queryId={query.id}
orderedColumnKeys={results.columns.map(
col => col.column_name,
)}
height={height}
filterText={searchText}
expandedColumns={expandedColumns}
allowHTML={allowHTML}
/>
)}
</AutoSizer>
</div>
</ResultContainer>
);
}

View File

@@ -50,7 +50,7 @@ import type {
CursorPosition,
} from 'src/SqlLab/types';
import type { DatabaseObject } from 'src/features/databases/types';
import { debounce, throttle, isEmpty } from 'lodash';
import { debounce, isEmpty } from 'lodash';
import Mousetrap from 'mousetrap';
import {
Alert,
@@ -98,7 +98,6 @@ import {
INITIAL_NORTH_PERCENT,
INITIAL_SOUTH_PERCENT,
SET_QUERY_EDITOR_SQL_DEBOUNCE_MS,
WINDOW_RESIZE_THROTTLE_MS,
} from 'src/SqlLab/constants';
import {
getItem,
@@ -300,7 +299,6 @@ const SqlEditor: FC<Props> = ({
const logAction = useLogAction({ queryEditorId: queryEditor.id });
const isActive = currentQueryEditorId === queryEditor.id;
const [height, setHeight] = useState(0);
const [autorun, setAutorun] = useState(queryEditor.autorun);
const [ctas, setCtas] = useState('');
const [northPercent, setNorthPercent] = useState(
@@ -586,21 +584,12 @@ const SqlEditor: FC<Props> = ({
});
useEffect(() => {
// We need to measure the height of the sql editor post render to figure the height of
// the south pane so it gets rendered properly
setHeight(getSqlEditorHeight());
const handleWindowResizeWithThrottle = throttle(
() => setHeight(getSqlEditorHeight()),
WINDOW_RESIZE_THROTTLE_MS,
);
if (isActive) {
loadQueryEditor();
window.addEventListener('resize', handleWindowResizeWithThrottle);
window.addEventListener('beforeunload', onBeforeUnload);
}
return () => {
window.removeEventListener('resize', handleWindowResizeWithThrottle);
window.removeEventListener('beforeunload', onBeforeUnload);
};
// TODO: Remove useEffectEvent deps once https://github.com/facebook/react/pull/25881 is released
@@ -982,6 +971,7 @@ const SqlEditor: FC<Props> = ({
);
const queryPane = () => {
const height = getSqlEditorHeight();
const { aceEditorHeight, southPaneHeight } =
getAceEditorAndSouthPaneHeights(height, northPercent, southPercent);
return (

View File

@@ -17,7 +17,6 @@
* under the License.
*/
import { useMemo, useRef, useCallback } from 'react';
import { styled } from '@superset-ui/core';
import { GridSize } from 'src/components/GridTable/constants';
import { GridTable } from 'src/components/GridTable';
import { type ColDef } from 'src/components/GridTable/types';
@@ -31,11 +30,6 @@ import type { FilterableTableProps, Datum, CellDataType } from './types';
// See https://stackoverflow.com/a/30987109 for more details
const ONLY_NUMBER_REGEX = /^(NaN|-?((\d*\.\d+|\d+)([Ee][+-]?\d+)?|Infinity))$/;
const StyledFilterableTable = styled.div`
height: 100%;
overflow: hidden;
`;
const parseNumberFromString = (value: string | number | null) => {
if (typeof value === 'string' && ONLY_NUMBER_REGEX.test(value)) {
return parseFloat(value);
@@ -126,14 +120,11 @@ export const FilterableTable = ({
}, []);
return (
<StyledFilterableTable
className="filterable-table-container"
data-test="table-container"
>
<div className="filterable-table-container" data-test="table-container">
<GridTable
size={GridSize.Small}
height={height}
usePagination={false}
height={height}
columns={columns}
data={data}
externalFilter={keywordFilter}
@@ -142,7 +133,7 @@ export const FilterableTable = ({
enableActions
columnReorderable
/>
</StyledFilterableTable>
</div>
);
};