Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sqllab): Grid header menu #32381

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions superset-frontend/src/components/GridTable/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,13 @@ const SortSeqLabel = styled.span`
const HeaderAction = styled.div`
display: none;
position: absolute;
right: ${({ theme }) => theme.gridUnit * 3}px;
right: 0;
&.main {
margin: 0 auto;
left: 0;
right: 0;
width: 20px;
flex-direction: row;
justify-content: center;
width: 100%;
}
& .ant-dropdown-trigger {
& .antd5-dropdown-trigger {
cursor: context-menu;
padding: ${({ theme }) => theme.gridUnit * 2}px;
background-color: var(--ag-background-color);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jest.mock('src/components/Icons', () => ({
}));

jest.mock('src/components/Dropdown', () => ({
Dropdown: ({ overlay }: { overlay: React.ReactChild }) => (
MenuDotsDropdown: ({ overlay }: { overlay: React.ReactChild }) => (
<div data-test="mock-Dropdown">{overlay}</div>
),
}));
Expand Down
97 changes: 48 additions & 49 deletions superset-frontend/src/components/GridTable/HeaderMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,13 @@ import { styled, t } from '@superset-ui/core';
import type { Column, ColumnPinnedType, GridApi } from 'ag-grid-community';

import Icons from 'src/components/Icons';
import { Dropdown, DropdownProps } from 'src/components/Dropdown';
import { MenuDotsDropdown, DropdownProps } from 'src/components/Dropdown';
import { Menu } from 'src/components/Menu';
import copyTextToClipboard from 'src/utils/copy';
import { PIVOT_COL_ID } from './constants';

const IconMenuItem = styled(Menu.Item)`
display: flex;
align-items: center;
`;
const IconEmpty = styled.span`
width: 20px;
width: 14px;
`;

type Params = {
Expand All @@ -42,7 +38,7 @@ type Params = {
pinnedRight?: boolean;
invisibleColumns: Column[];
isMain?: boolean;
onVisibleChange: DropdownProps['onVisibleChange'];
onVisibleChange: DropdownProps['onOpenChange'];
};

const HeaderMenu: React.FC<Params> = ({
Expand All @@ -62,14 +58,7 @@ const HeaderMenu: React.FC<Params> = ({
);

const unHideAction = invisibleColumns.length > 0 && (
<Menu.SubMenu
title={
<>
<Icons.EyeOutlined iconSize="m" />
{t('Unhide')}
</>
}
>
<Menu.SubMenu title={t('Unhide')} icon={<Icons.EyeOutlined iconSize="m" />}>
{invisibleColumns.length > 1 && (
<Menu.Item
onClick={() => {
Expand All @@ -94,13 +83,13 @@ const HeaderMenu: React.FC<Params> = ({

if (isMain) {
return (
<Dropdown
<MenuDotsDropdown
placement="bottomLeft"
trigger={['click']}
onVisibleChange={onVisibleChange}
onOpenChange={onVisibleChange}
overlay={
<Menu style={{ width: 250 }} mode="vertical">
<IconMenuItem
<Menu.Item
onClick={() => {
copyTextToClipboard(
() =>
Expand All @@ -121,10 +110,11 @@ const HeaderMenu: React.FC<Params> = ({
}),
);
}}
icon={<Icons.CopyOutlined iconSize="m" />}
>
<Icons.CopyOutlined iconSize="m" /> {t('Copy the current data')}
</IconMenuItem>
<IconMenuItem
{t('Copy the current data')}
</Menu.Item>
<Menu.Item
onClick={() => {
api.exportDataAsCsv({
columnKeys: api
Expand All @@ -133,21 +123,22 @@ const HeaderMenu: React.FC<Params> = ({
.filter(id => id !== colId),
});
}}
icon={<Icons.DownloadOutlined iconSize="m" />}
>
<Icons.DownloadOutlined iconSize="m" /> {t('Download to CSV')}
</IconMenuItem>
{t('Download to CSV')}
</Menu.Item>
<Menu.Divider />
<IconMenuItem
<Menu.Item
onClick={() => {
api.autoSizeAllColumns();
}}
icon={<Icons.ColumnWidthOutlined iconSize="m" />}
>
<Icons.ColumnWidthOutlined iconSize="m" />
{t('Autosize all columns')}
</IconMenuItem>
</Menu.Item>
{unHideAction}
<Menu.Divider />
<IconMenuItem
<Menu.Item
onClick={() => {
api.setColumnsVisible(invisibleColumns, true);
const columns = api.getColumns();
Expand All @@ -165,24 +156,24 @@ const HeaderMenu: React.FC<Params> = ({
}
}
}}
icon={<IconEmpty className="anticon" />}
>
<IconEmpty className="anticon" />
{t('Reset columns')}
</IconMenuItem>
</Menu.Item>
</Menu>
}
/>
);
}

return (
<Dropdown
<MenuDotsDropdown
placement="bottomRight"
trigger={['click']}
onVisibleChange={onVisibleChange}
onOpenChange={onVisibleChange}
overlay={
<Menu style={{ width: 180 }} mode="vertical">
<IconMenuItem
<Menu.Item
onClick={() => {
copyTextToClipboard(
() =>
Expand All @@ -199,44 +190,52 @@ const HeaderMenu: React.FC<Params> = ({
}),
);
}}
icon={<Icons.CopyOutlined iconSize="m" />}
>
<Icons.CopyOutlined iconSize="m" /> {t('Copy')}
</IconMenuItem>
{t('Copy')}
</Menu.Item>
{(pinnedLeft || pinnedRight) && (
<IconMenuItem onClick={() => pinColumn(null)}>
<Icons.UnlockOutlined iconSize="m" /> {t('Unpin')}
</IconMenuItem>
<Menu.Item
onClick={() => pinColumn(null)}
icon={<Icons.UnlockOutlined iconSize="m" />}
>
{t('Unpin')}
</Menu.Item>
)}
{!pinnedLeft && (
<IconMenuItem onClick={() => pinColumn('left')}>
<Icons.VerticalRightOutlined iconSize="m" />
<Menu.Item
onClick={() => pinColumn('left')}
icon={<Icons.VerticalRightOutlined iconSize="m" />}
>
{t('Pin Left')}
</IconMenuItem>
</Menu.Item>
)}
{!pinnedRight && (
<IconMenuItem onClick={() => pinColumn('right')}>
<Icons.VerticalLeftOutlined iconSize="m" />
<Menu.Item
onClick={() => pinColumn('right')}
icon={<Icons.VerticalLeftOutlined iconSize="m" />}
>
{t('Pin Right')}
</IconMenuItem>
</Menu.Item>
)}
<Menu.Divider />
<IconMenuItem
<Menu.Item
onClick={() => {
api.autoSizeColumns([colId]);
}}
icon={<Icons.ColumnWidthOutlined iconSize="m" />}
>
<Icons.ColumnWidthOutlined iconSize="m" />
{t('Autosize Column')}
</IconMenuItem>
<IconMenuItem
</Menu.Item>
<Menu.Item
onClick={() => {
api.setColumnsVisible([colId], false);
}}
disabled={api.getColumns()?.length === invisibleColumns.length + 1}
icon={<Icons.EyeInvisibleOutlined iconSize="m" />}
>
<Icons.EyeInvisibleOutlined iconSize="m" />
{t('Hide Column')}
</IconMenuItem>
</Menu.Item>
{unHideAction}
</Menu>
}
Expand Down
4 changes: 2 additions & 2 deletions superset-frontend/src/components/GridTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function GridTable<RecordType extends object>({
field: PIVOT_COL_ID,
valueGetter: 'node.rowIndex+1',
cellClass: 'locked-col',
width: 20 + rowIndexLength * 6,
width: 30 + rowIndexLength * 6,
suppressNavigable: true,
resizable: false,
pinned: 'left' as const,
Expand Down Expand Up @@ -218,7 +218,7 @@ function GridTable<RecordType extends object>({
overflow: hidden;
}
& [role='columnheader']:hover .customHeaderAction {
display: block;
display: flex;
}
`}
/>
Expand Down
3 changes: 3 additions & 0 deletions superset-frontend/src/components/Menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ const StyledSubMenu = styled(AntdMenu.SubMenu)`
}
}
}
.antd5-dropdown-menu-submenu-title {
align-items: center;
}
.antd5-menu-submenu-title {
display: flex;
flex-direction: row-reverse;
Expand Down
Loading