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

Add tooltips to overflow text on streams table #21253

Merged
merged 18 commits into from
Jan 19, 2023
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ $large: 200px;
.tableCell {
flex: 1 0 $medium;
min-width: $medium;
word-break: break-word;
overflow: hidden;
text-overflow: ellipsis;

[data-type="text"] {
word-break: break-word;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

&.xsmall {
flex-basis: $xsmall;
Expand All @@ -25,3 +29,7 @@ $large: 200px;
min-width: $large;
}
}

.noEllipsis > * {
overflow: visible;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import classNames from "classnames";
import React from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { useWindowSize } from "react-use";

import { Tooltip } from "components/ui/Tooltip";

import styles from "./CatalogTreeTableCell.module.scss";

Expand All @@ -8,6 +11,7 @@ type Sizes = "xsmall" | "small" | "medium" | "large";
interface CatalogTreeTableCellProps {
size?: Sizes;
className?: string;
withTooltip?: boolean;
}

// This lets us avoid the eslint complaint about unused styles
Expand All @@ -18,10 +22,63 @@ const sizeMap: Record<Sizes, string> = {
large: styles.large,
};

const TooltipText: React.FC<{ textNodes: Element[] }> = ({ textNodes }) => {
if (!textNodes.length) {
return null;
}
const text = textNodes.map((t) => decodeURIComponent(t.innerHTML)).join(" | ");
return <div dangerouslySetInnerHTML={{ __html: text }} />;
};

export const CatalogTreeTableCell: React.FC<React.PropsWithChildren<CatalogTreeTableCellProps>> = ({
size = "medium",
withTooltip,
className,
children,
}) => {
return <div className={classNames(styles.tableCell, className, sizeMap[size])}>{children}</div>;
const [tooltipDisabled, setTooltipDisabled] = useState(true);
const [textNodes, setTextNodes] = useState<Element[]>([]);
const cell = useRef<HTMLDivElement | null>(null);

const { width: windowWidth } = useWindowSize();

const getTextNodes = useCallback(() => {
if (withTooltip && cell.current) {
setTextNodes(Array.from(cell.current.querySelectorAll(`[data-type="text"]`)));
}
}, [withTooltip]);

useEffect(() => {
// windowWidth is only here so this functionality changes based on window width
if (textNodes.length && windowWidth) {
const [scrollWidths, clientWidths] = textNodes.reduce(
([scrollWidths, clientWidths], textNode) => {
if (textNode) {
scrollWidths += textNode.scrollWidth;
clientWidths += textNode.clientWidth;
}
return [scrollWidths, clientWidths];
},
[0, 0]
);

if (scrollWidths > clientWidths) {
setTooltipDisabled(false);
} else {
setTooltipDisabled(true);
}
}
}, [textNodes, windowWidth]);

return (
<div ref={cell} className={classNames(styles.tableCell, className, sizeMap[size])} onMouseEnter={getTextNodes}>
{withTooltip ? (
<Tooltip className={styles.noEllipsis} control={children} placement="bottom-start" disabled={tooltipDisabled}>
<TooltipText textNodes={textNodes} />
</Tooltip>
) : (
children
)}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,17 @@ export const CatalogTreeTableRow: React.FC<StreamHeaderProps> = ({
<Switch size="sm" checked={stream.config?.selected} onChange={onSelectStream} disabled={disabled} />
</CatalogTreeTableCell>
{/* <Cell>{fieldCount}</Cell> */}
krishnaglick marked this conversation as resolved.
Show resolved Hide resolved
<CatalogTreeTableCell>
<CatalogTreeTableCell withTooltip>
<Text size="md" className={styles.cellText}>
{stream.stream?.namespace || <FormattedMessage id="form.noNamespace" />}
</Text>
</CatalogTreeTableCell>
<CatalogTreeTableCell>
<CatalogTreeTableCell withTooltip>
<Text size="md" className={styles.cellText}>
{stream.stream?.name}
</Text>
</CatalogTreeTableCell>
<CatalogTreeTableCell size="large">
<CatalogTreeTableCell size="large" withTooltip>
{disabled ? (
<Text size="md" className={styles.cellText}>
{syncSchema.syncMode}
Expand All @@ -104,7 +104,7 @@ export const CatalogTreeTableRow: React.FC<StreamHeaderProps> = ({
/>
)}
</CatalogTreeTableCell>
<CatalogTreeTableCell>
<CatalogTreeTableCell withTooltip={pkType === "sourceDefined"}>
{pkType && (
<StreamPathSelect
pathType={pkType}
Expand All @@ -120,12 +120,12 @@ export const CatalogTreeTableRow: React.FC<StreamHeaderProps> = ({
<CatalogTreeTableCell size="xsmall">
<ArrowRightIcon />
</CatalogTreeTableCell>
<CatalogTreeTableCell>
<CatalogTreeTableCell withTooltip>
<Text size="md" className={styles.cellText}>
{destNamespace}
</Text>
</CatalogTreeTableCell>
<CatalogTreeTableCell>
<CatalogTreeTableCell withTooltip>
<Text size="md" className={styles.cellText}>
{destName}
</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ exports[`<BulkEditPanel /> should render 1`] = `
>
<span
class="<removed-for-snapshot-test>"
data-type="text"
/>
</div>
<svg
Expand Down Expand Up @@ -146,6 +147,7 @@ exports[`<BulkEditPanel /> should render 1`] = `
>
<span
class="<removed-for-snapshot-test>"
data-type="text"
>
Not available
</span>
Expand Down Expand Up @@ -210,6 +212,7 @@ exports[`<BulkEditPanel /> should render 1`] = `
>
<span
class="<removed-for-snapshot-test>"
data-type="text"
>
Not available
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ exports[`SchemaChangesBackdrop renders if there are non-breaking changes and pre
</div>
<p
class="text md text"
data-type="text"
>
Please review the schema updates before making changes to the connection
</p>
Expand Down Expand Up @@ -181,6 +182,7 @@ exports[`SchemaChangesBackdrop renders with breaking changes and prevents backgr
</div>
<p
class="text md text"
data-type="text"
>
Please review the schema updates before making changes to the connection
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ exports[`CreateConnectionForm should render 1`] = `
</span>
<p
class="<removed-for-snapshot-test>"
data-type="text"
>
Optional
</p>
Expand Down Expand Up @@ -1072,11 +1073,13 @@ exports[`CreateConnectionForm should render with an error 1`] = `
</div>
<p
class="<removed-for-snapshot-test>"
data-type="text"
>
Failed to fetch schema. Please try again
</p>
<p
class="<removed-for-snapshot-test>"
data-type="text"
>
Error: Test Error
</p>
Expand Down
1 change: 1 addition & 0 deletions airbyte-webapp/src/components/ui/Text/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const Text: React.FC<React.PropsWithChildren<TextProps>> = React.memo(

return React.createElement(as, {
...remainingProps,
"data-type": "text",
className,
children,
});
Expand Down
15 changes: 8 additions & 7 deletions airbyte-webapp/src/components/ui/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable jsx-a11y/mouse-events-have-key-events */
import { autoUpdate, flip, offset, shift, useFloating, UseFloatingProps } from "@floating-ui/react-dom";
import classNames from "classnames";
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useMemo } from "react";
import { createPortal } from "react-dom";

import { tooltipContext } from "./context";
Expand Down Expand Up @@ -54,7 +54,7 @@ export const Tooltip: React.FC<React.PropsWithChildren<TooltipProps>> = (props)
};
}, [isMouseOver]);

const canShowTooltip = isVisible && !disabled;
const canShowTooltip = useMemo(() => isVisible && !disabled, [disabled, isVisible]);

const onMouseOver = () => {
setIsMouseOver(true);
Expand All @@ -75,8 +75,8 @@ export const Tooltip: React.FC<React.PropsWithChildren<TooltipProps>> = (props)
>
{control}
</span>
{canShowTooltip &&
createPortal(
{createPortal(
canShowTooltip ? (
<div
role="tooltip"
ref={floating}
Expand All @@ -90,9 +90,10 @@ export const Tooltip: React.FC<React.PropsWithChildren<TooltipProps>> = (props)
onMouseOut={onMouseOut}
>
<tooltipContext.Provider value={props}>{children}</tooltipContext.Provider>
</div>,
document.body
)}
</div>
) : null,
document.body
)}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ exports[`ConnectionReplicationPage should render 1`] = `
</span>
<p
class="<removed-for-snapshot-test>"
data-type="text"
>
Optional
</p>
Expand Down Expand Up @@ -883,6 +884,7 @@ exports[`ConnectionReplicationPage should show an error if there is a schemaErro
</div>
<p
class="<removed-for-snapshot-test>"
data-type="text"
>
Failed to fetch schema. Please try again
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exports[`<mockFrequentlyUsedConnectors /> should renders with mock data without
>
<p
class="<removed-for-snapshot-test>"
data-type="text"
>
Most frequently used destinations
</p>
Expand Down