mirror of
https://github.com/apache/superset.git
synced 2026-04-19 08:04:53 +00:00
fix(SqlLab): South pane visual changes (#35601)
This commit is contained in:
committed by
GitHub
parent
0bf34d4d6f
commit
6e60a00d69
@@ -27,6 +27,7 @@ import {
|
||||
css,
|
||||
FeatureFlag,
|
||||
isFeatureEnabled,
|
||||
useTheme,
|
||||
} from '@superset-ui/core';
|
||||
import QueryTable from 'src/SqlLab/components/QueryTable';
|
||||
import { SqlLabRootState } from 'src/SqlLab/types';
|
||||
@@ -67,6 +68,7 @@ const QueryHistory = ({
|
||||
const { id, tabViewId } = useQueryEditor(String(queryEditorId), [
|
||||
'tabViewId',
|
||||
]);
|
||||
const theme = useTheme();
|
||||
const editorId = tabViewId ?? id;
|
||||
const [ref, hasReachedBottom] = useInView({ threshold: 0 });
|
||||
const [pageIndex, setPageIndex] = useState(0);
|
||||
@@ -118,7 +120,11 @@ const QueryHistory = ({
|
||||
}
|
||||
|
||||
return editorQueries.length > 0 ? (
|
||||
<>
|
||||
<div
|
||||
css={css`
|
||||
padding-left: ${theme.sizeUnit * 4}px;
|
||||
`}
|
||||
>
|
||||
<QueryTable
|
||||
columns={[
|
||||
'state',
|
||||
@@ -144,7 +150,7 @@ const QueryHistory = ({
|
||||
/>
|
||||
)}
|
||||
{isFetching && <Skeleton active />}
|
||||
</>
|
||||
</div>
|
||||
) : (
|
||||
<StyledEmptyStateWrapper>
|
||||
<EmptyState
|
||||
|
||||
@@ -148,6 +148,7 @@ const ReturnedRows = styled.div`
|
||||
const ResultSetControls = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-left: ${({ theme }) => theme.sizeUnit * 4}px;
|
||||
`;
|
||||
|
||||
const ResultSetButtons = styled.div`
|
||||
@@ -669,6 +670,7 @@ const ResultSet = ({
|
||||
css={css`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-left: ${theme.sizeUnit * 4}px;
|
||||
align-items: center;
|
||||
gap: ${GAP}px;
|
||||
`}
|
||||
@@ -704,6 +706,7 @@ const ResultSet = ({
|
||||
<div
|
||||
css={css`
|
||||
flex: 1 1 auto;
|
||||
padding-left: ${theme.sizeUnit * 4}px;
|
||||
`}
|
||||
>
|
||||
<AutoSizer disableWidth>
|
||||
|
||||
@@ -185,6 +185,7 @@ const StyledSqlEditor = styled.div`
|
||||
|
||||
.queryPane {
|
||||
padding: ${theme.sizeUnit * 2}px;
|
||||
padding-left: 0px;
|
||||
+ .ant-splitter-bar .ant-splitter-bar-dragger {
|
||||
&::before {
|
||||
background: transparent;
|
||||
|
||||
@@ -138,32 +138,30 @@ test('renders preview', async () => {
|
||||
// eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks
|
||||
describe('table actions', () => {
|
||||
test('refreshes table metadata when triggered', async () => {
|
||||
const { getByRole, getByText } = render(<TablePreview {...mockedProps} />, {
|
||||
const { getByRole } = render(<TablePreview {...mockedProps} />, {
|
||||
useRedux: true,
|
||||
initialState,
|
||||
});
|
||||
await waitFor(() =>
|
||||
expect(fetchMock.calls(getTableMetadataEndpoint)).toHaveLength(1),
|
||||
);
|
||||
const menuButton = getByRole('button', { name: /Table actions/i });
|
||||
fireEvent.click(menuButton);
|
||||
fireEvent.click(getByText('Refresh table schema'));
|
||||
const refreshButton = getByRole('button', { name: 'sync' });
|
||||
fireEvent.click(refreshButton);
|
||||
await waitFor(() =>
|
||||
expect(fetchMock.calls(getTableMetadataEndpoint)).toHaveLength(2),
|
||||
);
|
||||
});
|
||||
|
||||
test('shows CREATE VIEW statement', async () => {
|
||||
const { getByRole, getByText } = render(<TablePreview {...mockedProps} />, {
|
||||
const { getByRole } = render(<TablePreview {...mockedProps} />, {
|
||||
useRedux: true,
|
||||
initialState,
|
||||
});
|
||||
await waitFor(() =>
|
||||
expect(fetchMock.calls(getTableMetadataEndpoint)).toHaveLength(1),
|
||||
);
|
||||
const menuButton = getByRole('button', { name: /Table actions/i });
|
||||
fireEvent.click(menuButton);
|
||||
fireEvent.click(getByText('Show CREATE VIEW statement'));
|
||||
const viewButton = getByRole('button', { name: 'eye' });
|
||||
fireEvent.click(viewButton);
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
screen.queryByRole('dialog', { name: 'CREATE VIEW statement' }),
|
||||
|
||||
@@ -25,15 +25,15 @@ import {
|
||||
getExtensionsRegistry,
|
||||
styled,
|
||||
t,
|
||||
useTheme,
|
||||
} from '@superset-ui/core';
|
||||
import {
|
||||
SafeMarkdown,
|
||||
Alert,
|
||||
Breadcrumb,
|
||||
Button,
|
||||
Card,
|
||||
Dropdown,
|
||||
Skeleton,
|
||||
Flex,
|
||||
} from '@superset-ui/core/components';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import { Icons } from '@superset-ui/core/components/Icons';
|
||||
@@ -47,7 +47,7 @@ import {
|
||||
useTableMetadataQuery,
|
||||
} from 'src/hooks/apiResources';
|
||||
import { runTablePreviewQuery } from 'src/SqlLab/actions/sqlLab';
|
||||
import { Menu } from '@superset-ui/core/components/Menu';
|
||||
import { ActionButton } from '@superset-ui/core/components/ActionButton';
|
||||
import ResultSet from '../ResultSet';
|
||||
import ShowSQL from '../ShowSQL';
|
||||
|
||||
@@ -68,23 +68,6 @@ const TABS_KEYS = {
|
||||
INDEXES: 'indexes',
|
||||
SAMPLE: 'sample',
|
||||
};
|
||||
const MENUS = [
|
||||
{
|
||||
key: 'refresh-table',
|
||||
label: t('Refresh table schema'),
|
||||
icon: <Icons.SyncOutlined iconSize="s" aria-hidden />,
|
||||
},
|
||||
{
|
||||
key: 'copy-select-statement',
|
||||
label: t('Copy SELECT statement'),
|
||||
icon: <Icons.CopyOutlined iconSize="s" aria-hidden />,
|
||||
},
|
||||
{
|
||||
key: 'show-create-view-statement',
|
||||
label: t('Show CREATE VIEW statement'),
|
||||
icon: <Icons.EyeOutlined iconSize="s" aria-hidden />,
|
||||
},
|
||||
];
|
||||
const TAB_HEADER_HEIGHT = 80;
|
||||
const PREVIEW_QUERY_LIMIT = 100;
|
||||
|
||||
@@ -96,6 +79,8 @@ const Title = styled.div`
|
||||
column-gap: ${theme.sizeUnit}px;
|
||||
font-size: ${theme.fontSizeLG}px;
|
||||
font-weight: ${theme.fontWeightStrong};
|
||||
padding-top: ${theme.sizeUnit * 2}px;
|
||||
padding-left: ${theme.sizeUnit * 4}px;
|
||||
`}
|
||||
`;
|
||||
const renderWell = (partitions: TableMetaData['partitions']) => {
|
||||
@@ -133,6 +118,7 @@ const renderWell = (partitions: TableMetaData['partitions']) => {
|
||||
|
||||
const TablePreview: FC<Props> = ({ dbId, catalog, schema, tableName }) => {
|
||||
const dispatch = useDispatch();
|
||||
const theme = useTheme();
|
||||
const [databaseName, backend, disableDataPreview] = useSelector<
|
||||
SqlLabRootState,
|
||||
string[]
|
||||
@@ -240,16 +226,37 @@ const TablePreview: FC<Props> = ({ dbId, catalog, schema, tableName }) => {
|
||||
],
|
||||
);
|
||||
|
||||
const dropdownMenu = useMemo(() => {
|
||||
let menus = [...MENUS];
|
||||
if (!tableData.selectStar) {
|
||||
menus = menus.filter(({ key }) => key !== 'copy-select-statement');
|
||||
}
|
||||
if (!tableData.view) {
|
||||
menus = menus.filter(({ key }) => key !== 'show-create-view-statement');
|
||||
}
|
||||
return menus;
|
||||
}, [tableData.view, tableData.selectStar]);
|
||||
const titleActions = () => (
|
||||
<Flex
|
||||
align="center"
|
||||
css={css`
|
||||
padding-left: ${theme.sizeUnit * 2}px;
|
||||
`}
|
||||
>
|
||||
<ActionButton
|
||||
label={t('Refresh table schema')}
|
||||
tooltip={t('Refresh table schema')}
|
||||
icon={<Icons.SyncOutlined iconSize="m" />}
|
||||
onClick={refreshTableMetadata}
|
||||
/>
|
||||
{tableData.selectStar && (
|
||||
<ActionButton
|
||||
label={t('Copy SELECT statement')}
|
||||
icon={<Icons.CopyOutlined iconSize="m" />}
|
||||
tooltip={t('Copy SELECT statement')}
|
||||
onClick={() => copyStatementActionRef.current?.click()}
|
||||
/>
|
||||
)}
|
||||
{tableData.view && (
|
||||
<ActionButton
|
||||
label={t('Show CREATE VIEW statement')}
|
||||
icon={<Icons.EyeOutlined iconSize="m" />}
|
||||
tooltip={t('Show CREATE VIEW statement')}
|
||||
onClick={() => showViewStatementActionRef.current?.click()}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
|
||||
if (isMetadataLoading) {
|
||||
return <Skeleton active />;
|
||||
@@ -282,7 +289,12 @@ const TablePreview: FC<Props> = ({ dbId, catalog, schema, tableName }) => {
|
||||
flex-direction: column;
|
||||
`}
|
||||
>
|
||||
<Breadcrumb separator=">">
|
||||
<Breadcrumb
|
||||
separator=">"
|
||||
css={css`
|
||||
padding-left: ${theme.sizeUnit * 4}px;
|
||||
`}
|
||||
>
|
||||
<Breadcrumb.Item>{backend}</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>{databaseName}</Breadcrumb.Item>
|
||||
{catalog && <Breadcrumb.Item>{catalog}</Breadcrumb.Item>}
|
||||
@@ -315,33 +327,7 @@ const TablePreview: FC<Props> = ({ dbId, catalog, schema, tableName }) => {
|
||||
<Title>
|
||||
<Icons.InsertRowAboveOutlined iconSize="l" />
|
||||
{tableName}
|
||||
<Dropdown
|
||||
popupRender={() => (
|
||||
<Menu
|
||||
onClick={({ key }) => {
|
||||
if (key === 'refresh-table') {
|
||||
refreshTableMetadata();
|
||||
}
|
||||
if (key === 'copy-select-statement') {
|
||||
copyStatementActionRef.current?.click();
|
||||
}
|
||||
if (key === 'show-create-view-statement') {
|
||||
showViewStatementActionRef.current?.click();
|
||||
}
|
||||
}}
|
||||
items={dropdownMenu}
|
||||
/>
|
||||
)}
|
||||
trigger={['click']}
|
||||
>
|
||||
<Button buttonSize="xsmall" buttonStyle="link">
|
||||
<Icons.DownSquareOutlined
|
||||
iconSize="m"
|
||||
style={{ marginTop: 2, marginLeft: 4 }}
|
||||
aria-label={t('Table actions')}
|
||||
/>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
{titleActions()}
|
||||
</Title>
|
||||
{isMetadataRefreshing ? (
|
||||
<Skeleton active />
|
||||
@@ -440,7 +426,11 @@ const TablePreview: FC<Props> = ({ dbId, catalog, schema, tableName }) => {
|
||||
css={css`
|
||||
height: ${height}px;
|
||||
`}
|
||||
tabBarStyle={{ paddingLeft: theme.sizeUnit * 4 }}
|
||||
items={tabItems}
|
||||
contentStyle={css`
|
||||
padding-left: ${theme.sizeUnit * 4}px;
|
||||
`}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user