mirror of
https://github.com/apache/superset.git
synced 2024-09-12 08:39:45 -04:00
fix(column-header-tooltip): make that hide the tooltip when the cloum… (#18988)
* fix(column-header-tooltip): make that hide the tooltip when the cloumn header is turncated * fix(column-header-tooltip): fix lint * fix(column-header-tooltip): make to dynamic tooltip header in FilterTable * fix(column-header-tooltip): make to fix the lint issue * fix(column-header-tooltip): make to remove the tooltip option * fix(column-header-tooltip): make to add test and storybook for dynamic tooltip * fix(column-header-tooltip): make to fix lint
This commit is contained in:
parent
85b0ef8526
commit
741033e87d
@ -30,7 +30,6 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
} from 'react-virtualized';
|
} from 'react-virtualized';
|
||||||
import { getMultipleTextDimensions, t, styled } from '@superset-ui/core';
|
import { getMultipleTextDimensions, t, styled } from '@superset-ui/core';
|
||||||
import { Tooltip } from 'src/components/Tooltip';
|
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
import CopyToClipboard from '../CopyToClipboard';
|
import CopyToClipboard from '../CopyToClipboard';
|
||||||
import ModalTrigger from '../ModalTrigger';
|
import ModalTrigger from '../ModalTrigger';
|
||||||
@ -312,14 +311,15 @@ export default class FilterableTable extends PureComponent<
|
|||||||
this.props.orderedColumnKeys.forEach((key, index) => {
|
this.props.orderedColumnKeys.forEach((key, index) => {
|
||||||
// we can't use Math.max(...colWidths.slice(...)) here since the number
|
// we can't use Math.max(...colWidths.slice(...)) here since the number
|
||||||
// of elements might be bigger than the number of allowed arguments in a
|
// of elements might be bigger than the number of allowed arguments in a
|
||||||
// JavaScript function
|
// Javascript function
|
||||||
widthsByColumnKey[key] =
|
const value = (widthsByColumnKey[key] =
|
||||||
colWidths
|
colWidths
|
||||||
.slice(
|
.slice(
|
||||||
index * (this.list.length + 1),
|
index * (this.list.length + 1),
|
||||||
(index + 1) * (this.list.length + 1),
|
(index + 1) * (this.list.length + 1),
|
||||||
)
|
)
|
||||||
.reduce((a, b) => Math.max(a, b)) + PADDING;
|
.reduce((a, b) => Math.max(a, b)) + PADDING);
|
||||||
|
widthsByColumnKey[key] = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
return widthsByColumnKey;
|
return widthsByColumnKey;
|
||||||
@ -513,20 +513,12 @@ export default class FilterableTable extends PureComponent<
|
|||||||
this.props.expandedColumns.indexOf(label) > -1
|
this.props.expandedColumns.indexOf(label) > -1
|
||||||
? 'header-style-disabled'
|
? 'header-style-disabled'
|
||||||
: 'header-style';
|
: 'header-style';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<div className={className}>
|
||||||
id="header-tooltip"
|
{label}
|
||||||
title={label}
|
{sortBy === dataKey && <SortIndicator sortDirection={sortDirection} />}
|
||||||
placement="topLeft"
|
</div>
|
||||||
css={{ display: 'block' }}
|
|
||||||
>
|
|
||||||
<div className={className}>
|
|
||||||
{label}
|
|
||||||
{sortBy === dataKey && (
|
|
||||||
<SortIndicator sortDirection={sortDirection} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,32 +537,25 @@ export default class FilterableTable extends PureComponent<
|
|||||||
? 'header-style-disabled'
|
? 'header-style-disabled'
|
||||||
: 'header-style';
|
: 'header-style';
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<div
|
||||||
key={key}
|
key={key}
|
||||||
id="header-tooltip"
|
style={{
|
||||||
title={label}
|
...style,
|
||||||
placement="topLeft"
|
top:
|
||||||
css={{ display: 'block' }}
|
typeof style.top === 'number'
|
||||||
|
? style.top - GRID_POSITION_ADJUSTMENT
|
||||||
|
: style.top,
|
||||||
|
}}
|
||||||
|
className={`${className} grid-cell grid-header-cell`}
|
||||||
|
role="columnheader"
|
||||||
|
tabIndex={columnIndex}
|
||||||
|
onClick={() => this.sortGrid(label)}
|
||||||
>
|
>
|
||||||
<div
|
{label}
|
||||||
style={{
|
{this.state.sortBy === label && (
|
||||||
...style,
|
<SortIndicator sortDirection={this.state.sortDirection} />
|
||||||
top:
|
)}
|
||||||
typeof style.top === 'number'
|
</div>
|
||||||
? style.top - GRID_POSITION_ADJUSTMENT
|
|
||||||
: style.top,
|
|
||||||
}}
|
|
||||||
className={`${className} grid-cell grid-header-cell`}
|
|
||||||
role="columnheader"
|
|
||||||
tabIndex={columnIndex}
|
|
||||||
onClick={() => this.sortGrid(label)}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
{this.state.sortBy === label && (
|
|
||||||
<SortIndicator sortDirection={this.state.sortDirection} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
import TooltipParagraph from '.';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'DynamicTooltip',
|
||||||
|
component: TooltipParagraph,
|
||||||
|
};
|
||||||
|
|
||||||
|
type IProps = {
|
||||||
|
title: string;
|
||||||
|
width: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const InteractiveTooltip = (args: IProps) => (
|
||||||
|
<div style={{ width: `${args.width}px`, margin: '50px 100px' }}>
|
||||||
|
<TooltipParagraph>{args.title}</TooltipParagraph>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
InteractiveTooltip.story = {
|
||||||
|
parameters: {
|
||||||
|
knobs: {
|
||||||
|
disable: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
InteractiveTooltip.args = {
|
||||||
|
title: 'This is too long and should truncate.',
|
||||||
|
width: 200,
|
||||||
|
};
|
@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import TooltipParagraph from '.';
|
||||||
|
|
||||||
|
test('starts hidden with default props', () => {
|
||||||
|
render(<TooltipParagraph>This is tootlip description.</TooltipParagraph>);
|
||||||
|
expect(screen.queryByRole('tooltip')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('not render on hover when not truncated', async () => {
|
||||||
|
const { container } = render(
|
||||||
|
<div style={{ width: '200px' }}>
|
||||||
|
<TooltipParagraph>
|
||||||
|
<span data-test="test-text">This is short</span>
|
||||||
|
</TooltipParagraph>
|
||||||
|
</div>,
|
||||||
|
);
|
||||||
|
userEvent.hover(screen.getByTestId('test-text'));
|
||||||
|
await waitFor(() =>
|
||||||
|
expect(container.firstChild?.firstChild).not.toHaveClass(
|
||||||
|
'ant-tooltip-open',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('render on hover when truncated', async () => {
|
||||||
|
const { container } = render(
|
||||||
|
<div style={{ width: '200px' }}>
|
||||||
|
<TooltipParagraph>
|
||||||
|
<span data-test="test-text">This is too long and should truncate.</span>
|
||||||
|
</TooltipParagraph>
|
||||||
|
</div>,
|
||||||
|
);
|
||||||
|
userEvent.hover(screen.getByTestId('test-text'));
|
||||||
|
await waitFor(() =>
|
||||||
|
expect(container.firstChild?.firstChild).toHaveClass('ant-tooltip-open'),
|
||||||
|
);
|
||||||
|
});
|
43
superset-frontend/src/components/TooltipParagraph/index.tsx
Normal file
43
superset-frontend/src/components/TooltipParagraph/index.tsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Tooltip, Typography } from 'antd';
|
||||||
|
import { ParagraphProps } from 'antd/es/typography/Paragraph';
|
||||||
|
|
||||||
|
const TooltipParagraph: React.FC<ParagraphProps> = ({
|
||||||
|
children,
|
||||||
|
ellipsis,
|
||||||
|
...props
|
||||||
|
}) => {
|
||||||
|
const [truncated, setTruncated] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip title={truncated ? children : undefined}>
|
||||||
|
<Typography.Paragraph
|
||||||
|
{...props}
|
||||||
|
ellipsis={{ ...(ellipsis as any), onEllipsis: setTruncated }}
|
||||||
|
>
|
||||||
|
{/* NOTE: Fragment is necessary to avoid showing the title */}
|
||||||
|
<>{children}</>
|
||||||
|
</Typography.Paragraph>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TooltipParagraph;
|
Loading…
Reference in New Issue
Block a user