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(Explore): Show the tooltip only when label does not fit the container in METRICS/FILTERS/GROUP BY/SORT BY of the DATA panel #16060

Merged
merged 14 commits into from
Aug 12, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import OptionWrapper from 'src/explore/components/controls/DndColumnSelectContro
import { OptionSelector } from 'src/explore/components/controls/DndColumnSelectControl/utils';
import { DatasourcePanelDndItem } from 'src/explore/components/DatasourcePanel/types';
import { DndItemType } from 'src/explore/components/DndItemType';
import { StyledColumnOption } from 'src/explore/components/optionRenderers';
import { useComponentDidUpdate } from 'src/common/hooks/useComponentDidUpdate';

export const DndColumnSelect = (props: LabelProps) => {
Expand Down Expand Up @@ -123,9 +122,8 @@ export const DndColumnSelect = (props: LabelProps) => {
onShiftOptions={onShiftOptions}
type={`${DndItemType.ColumnOption}_${name}_${label}`}
canDelete={canDelete}
>
<StyledColumnOption column={column} showType />
</OptionWrapper>
column={column}
/>
)),
[
canDelete,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
t,
} from '@superset-ui/core';
import { ColumnMeta } from '@superset-ui/chart-controls';
import { Tooltip } from 'src/components/Tooltip';
import {
OPERATOR_ENUM_TO_OPERATOR_TYPE,
Operators,
Expand Down Expand Up @@ -299,6 +298,7 @@ export const DndFilterSelect = (props: DndFilterSelectProps) => {
() =>
values.map((adhocFilter: AdhocFilter, index: number) => {
const label = adhocFilter.getDefaultLabel();
const tooltipTitle = adhocFilter.getTooltipTitle();
return (
<AdhocFilterPopoverTrigger
key={index}
Expand All @@ -311,14 +311,14 @@ export const DndFilterSelect = (props: DndFilterSelectProps) => {
<OptionWrapper
key={index}
index={index}
label={label}
tooltipTitle={tooltipTitle}
clickClose={onClickClose}
onShiftOptions={onShiftOptions}
type={DndItemType.FilterOption}
withCaret
isExtra={adhocFilter.isExtra}
>
<Tooltip title={label}>{label}</Tooltip>
</OptionWrapper>
/>
</AdhocFilterPopoverTrigger>
);
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ test('renders with default props', () => {
clickClose={jest.fn()}
type={'Column' as DndItemType}
onShiftOptions={jest.fn()}
>
Option
</OptionWrapper>,
label="Option"
/>,
{ useDnd: true },
);
expect(container).toBeInTheDocument();
Expand All @@ -46,17 +45,15 @@ test('triggers onShiftOptions on drop', () => {
clickClose={jest.fn()}
type={'Column' as DndItemType}
onShiftOptions={onShiftOptions}
>
Option 1
</OptionWrapper>
label="Option 1"
/>
<OptionWrapper
index={2}
clickClose={jest.fn()}
type={'Column' as DndItemType}
onShiftOptions={onShiftOptions}
>
Option 2
</OptionWrapper>
label="Option 2"
/>
</>,
{ useDnd: true },
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,19 @@ import {
OptionProps,
OptionItemInterface,
} from 'src/explore/components/controls/DndColumnSelectControl/types';
import { Tooltip } from 'src/components/Tooltip';
import { StyledColumnOption } from 'src/explore/components/optionRenderers';
import { styled } from '@superset-ui/core';
import { ColumnMeta } from '@superset-ui/chart-controls';
import Option from './Option';

export const OptionLabel = styled.div`
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;

export default function OptionWrapper(
props: OptionProps & {
type: string;
Expand All @@ -38,16 +49,19 @@ export default function OptionWrapper(
) {
const {
index,
label,
tooltipTitle,
column,
type,
onShiftOptions,
clickClose,
withCaret,
isExtra,
canDelete = true,
children,
...rest
} = props;
const ref = useRef<HTMLDivElement>(null);
const labelRef = useRef<HTMLDivElement>(null);

const item: OptionItemInterface = useMemo(
() => ({
Expand All @@ -56,7 +70,7 @@ export default function OptionWrapper(
}),
[index, type],
);
const [, drag] = useDrag({
const [{ isDragging }, drag] = useDrag({
item,
collect: (monitor: DragSourceMonitor) => ({
isDragging: monitor.isDragging(),
Expand Down Expand Up @@ -107,6 +121,51 @@ export default function OptionWrapper(
},
});

const shouldShowTooltip =
(!isDragging && tooltipTitle && label && tooltipTitle !== label) ||
(!isDragging &&
labelRef &&
labelRef.current &&
labelRef.current.scrollWidth > labelRef.current.clientWidth);
Comment on lines +127 to +129
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
labelRef &&
labelRef.current &&
labelRef.current.scrollWidth > labelRef.current.clientWidth);
labelRef?.current?.scrollWidth > labelRef.current.clientWidth);

If you're feelin' fancy ¯\_(ツ)_/¯


const LabelContent = () => {
if (!shouldShowTooltip) {
return <span>{label}</span>;
}
return (
<Tooltip title={tooltipTitle || label}>
<span>{label}</span>
</Tooltip>
);
};

const ColumnOption = () => (
<StyledColumnOption
column={column as ColumnMeta}
labelRef={labelRef}
showTooltip={!!shouldShowTooltip}
showType
/>
);

const Label = () => {
if (label) {
return (
<OptionLabel ref={labelRef}>
<LabelContent />
</OptionLabel>
);
}
if (column) {
return (
<OptionLabel>
<ColumnOption />
</OptionLabel>
);
}
return null;
};

drag(drop(ref));

return (
Expand All @@ -118,7 +177,7 @@ export default function OptionWrapper(
isExtra={isExtra}
canDelete={canDelete}
>
{children}
<Label />
</Option>
</DragContainer>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ import { DatasourcePanelDndItem } from '../../DatasourcePanel/types';
import { DndItemType } from '../../DndItemType';

export interface OptionProps {
children: ReactNode;
children?: ReactNode;
index: number;
label?: string;
tooltipTitle?: string;
column?: ColumnMeta;
clickClose: (index: number) => void;
withCaret?: boolean;
isExtra?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@ export const OptionControlContainer = styled.div<{
border-radius: 3px;
cursor: ${({ withCaret }) => (withCaret ? 'pointer' : 'default')};
`;

export const Label = styled.div`
${({ theme }) => `
display: flex;
max-width: 100%;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
align-items: center;
Expand All @@ -71,6 +70,11 @@ export const Label = styled.div`
`}
`;

const LabelText = styled.span`
overflow: hidden;
text-overflow: ellipsis;
`;

export const CaretContainer = styled.div`
height: 100%;
border-left: solid 1px ${({ theme }) => theme.colors.grayscale.dark2}0C;
Expand Down Expand Up @@ -195,6 +199,8 @@ export const OptionControlLabel = ({
}) => {
const theme = useTheme();
const ref = useRef<HTMLDivElement>(null);
const labelRef = useRef<HTMLDivElement>(null);
const hasMetricName = savedMetric?.metric_name;
const [, drop] = useDrop({
accept: type,
drop() {
Expand Down Expand Up @@ -242,7 +248,7 @@ export const OptionControlLabel = ({
item.index = hoverIndex;
},
});
const [, drag] = useDrag({
const [{ isDragging }, drag] = useDrag({
item: {
type,
index,
Expand All @@ -254,10 +260,34 @@ export const OptionControlLabel = ({
});

const getLabelContent = () => {
if (savedMetric?.metric_name) {
return <StyledMetricOption metric={savedMetric} />;
const shouldShowTooltip =
(!isDragging &&
typeof label === 'string' &&
tooltipTitle &&
label &&
tooltipTitle !== label) ||
(!isDragging &&
labelRef &&
labelRef.current &&
labelRef.current.scrollWidth > labelRef.current.clientWidth);

if (savedMetric && hasMetricName) {
return (
<StyledMetricOption
metric={savedMetric}
labelRef={labelRef}
showTooltip={!!shouldShowTooltip}
/>
);
}
if (!shouldShowTooltip) {
return <LabelText ref={labelRef}>{label}</LabelText>;
}
return <Tooltip title={tooltipTitle}>{label}</Tooltip>;
return (
<Tooltip title={tooltipTitle || label}>
<LabelText ref={labelRef}>{label}</LabelText>
</Tooltip>
);
};

const getOptionControlContent = () => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from '@superset-ui/chart-controls';

const OptionContainer = styled.div`
width: 100%;
> span {
display: flex;
align-items: center;
Expand Down