mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-04 13:48:56 +02:00
feat: better tooltip links (#2891)
https://linear.app/unleash/issue/2-576/improve-how-text-that-has-tooltip-should-look-so-they-are-not   - Adapts the existing `HtmlTooltip` component to support setting `maxHeight` and `maxWidth` properties; - Introduces a new common component: `TooltipLink`; - Adapts SA (tokens), features (tags), variants (overrides, payloads) and project access (role and role description); - Role description in project access now uses this component instead of the old jankier popover component;
This commit is contained in:
parent
005e5b1d15
commit
4286103850
@ -1,22 +1,16 @@
|
|||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
import { Link, styled, Typography } from '@mui/material';
|
import { styled, Typography } from '@mui/material';
|
||||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
||||||
import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip';
|
|
||||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
||||||
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
||||||
import { IServiceAccount } from 'interfaces/service-account';
|
import { IServiceAccount } from 'interfaces/service-account';
|
||||||
import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell';
|
import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell';
|
||||||
|
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
|
||||||
|
|
||||||
const StyledItem = styled(Typography)(({ theme }) => ({
|
const StyledItem = styled(Typography)(({ theme }) => ({
|
||||||
fontSize: theme.fontSizes.smallerBody,
|
fontSize: theme.fontSizes.smallerBody,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledLink = styled(Link, {
|
|
||||||
shouldForwardProp: prop => prop !== 'highlighted',
|
|
||||||
})<{ highlighted?: boolean }>(({ theme, highlighted }) => ({
|
|
||||||
backgroundColor: highlighted ? theme.palette.highlight : 'transparent',
|
|
||||||
}));
|
|
||||||
|
|
||||||
interface IServiceAccountTokensCellProps {
|
interface IServiceAccountTokensCellProps {
|
||||||
serviceAccount: IServiceAccount;
|
serviceAccount: IServiceAccount;
|
||||||
value: string;
|
value: string;
|
||||||
@ -35,8 +29,8 @@ export const ServiceAccountTokensCell: VFC<IServiceAccountTokensCellProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TextCell>
|
<TextCell>
|
||||||
<HtmlTooltip
|
<TooltipLink
|
||||||
title={
|
tooltip={
|
||||||
<>
|
<>
|
||||||
{serviceAccount.tokens?.map(({ id, description }) => (
|
{serviceAccount.tokens?.map(({ id, description }) => (
|
||||||
<StyledItem key={id}>
|
<StyledItem key={id}>
|
||||||
@ -47,19 +41,15 @@ export const ServiceAccountTokensCell: VFC<IServiceAccountTokensCellProps> = ({
|
|||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
highlighted={
|
||||||
|
searchQuery.length > 0 &&
|
||||||
|
value.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<StyledLink
|
{serviceAccount.tokens?.length === 1
|
||||||
underline="always"
|
? '1 token'
|
||||||
highlighted={
|
: `${serviceAccount.tokens?.length} tokens`}
|
||||||
searchQuery.length > 0 &&
|
</TooltipLink>
|
||||||
value.toLowerCase().includes(searchQuery.toLowerCase())
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{serviceAccount.tokens?.length === 1
|
|
||||||
? '1 token'
|
|
||||||
: `${serviceAccount.tokens?.length} tokens`}
|
|
||||||
</StyledLink>
|
|
||||||
</HtmlTooltip>
|
|
||||||
</TextCell>
|
</TextCell>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,29 +1,44 @@
|
|||||||
import { styled, Tooltip, tooltipClasses, TooltipProps } from '@mui/material';
|
import { styled, Tooltip, tooltipClasses, TooltipProps } from '@mui/material';
|
||||||
|
import { SpacingArgument } from '@mui/system/createTheme/createSpacing';
|
||||||
|
|
||||||
const StyledHtmlTooltip = styled(({ className, ...props }: TooltipProps) => (
|
const StyledHtmlTooltip = styled(
|
||||||
<Tooltip {...props} classes={{ popper: className }} />
|
({ className, maxWidth, maxHeight, ...props }: IHtmlTooltipProps) => (
|
||||||
))(({ theme }) => ({
|
<Tooltip {...props} classes={{ popper: className }} />
|
||||||
maxWidth: theme.spacing(37.5),
|
),
|
||||||
[`& .${tooltipClasses.tooltip}`]: {
|
{
|
||||||
display: 'flex',
|
shouldForwardProp: prop => prop !== 'maxWidth' && prop !== 'maxHeight',
|
||||||
flexDirection: 'column',
|
}
|
||||||
backgroundColor: theme.palette.background.paper,
|
)<{ maxWidth?: SpacingArgument; maxHeight?: SpacingArgument }>(
|
||||||
padding: theme.spacing(1, 1.5),
|
({ theme, maxWidth, maxHeight }) => ({
|
||||||
borderRadius: theme.shape.borderRadiusMedium,
|
maxWidth: maxWidth || theme.spacing(37.5),
|
||||||
boxShadow: theme.shadows[2],
|
[`& .${tooltipClasses.tooltip}`]: {
|
||||||
color: theme.palette.text.primary,
|
display: 'flex',
|
||||||
fontWeight: theme.fontWeight.medium,
|
flexDirection: 'column',
|
||||||
maxWidth: 'inherit',
|
backgroundColor: theme.palette.background.paper,
|
||||||
border: `1px solid ${theme.palette.lightBorder}`,
|
padding: theme.spacing(1, 1.5),
|
||||||
},
|
borderRadius: theme.shape.borderRadiusMedium,
|
||||||
[`& .${tooltipClasses.arrow}`]: {
|
boxShadow: theme.shadows[2],
|
||||||
'&:before': {
|
color: theme.palette.text.primary,
|
||||||
|
fontWeight: theme.fontWeight.medium,
|
||||||
|
maxWidth: 'inherit',
|
||||||
border: `1px solid ${theme.palette.lightBorder}`,
|
border: `1px solid ${theme.palette.lightBorder}`,
|
||||||
|
maxHeight: maxHeight || theme.spacing(37.5),
|
||||||
|
overflow: 'auto',
|
||||||
},
|
},
|
||||||
color: theme.palette.background.paper,
|
[`& .${tooltipClasses.arrow}`]: {
|
||||||
},
|
'&:before': {
|
||||||
}));
|
border: `1px solid ${theme.palette.lightBorder}`,
|
||||||
|
},
|
||||||
|
color: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
export const HtmlTooltip = (props: TooltipProps) => (
|
export interface IHtmlTooltipProps extends TooltipProps {
|
||||||
|
maxWidth?: SpacingArgument;
|
||||||
|
maxHeight?: SpacingArgument;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const HtmlTooltip = (props: IHtmlTooltipProps) => (
|
||||||
<StyledHtmlTooltip {...props}>{props.children}</StyledHtmlTooltip>
|
<StyledHtmlTooltip {...props}>{props.children}</StyledHtmlTooltip>
|
||||||
);
|
);
|
||||||
|
@ -1,21 +1,15 @@
|
|||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
import { FeatureSchema } from 'openapi';
|
import { FeatureSchema } from 'openapi';
|
||||||
import { Link, styled, Typography } from '@mui/material';
|
import { styled, Typography } from '@mui/material';
|
||||||
import { TextCell } from '../TextCell/TextCell';
|
import { TextCell } from '../TextCell/TextCell';
|
||||||
import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip';
|
|
||||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
||||||
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
||||||
|
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
|
||||||
|
|
||||||
const StyledTag = styled(Typography)(({ theme }) => ({
|
const StyledTag = styled(Typography)(({ theme }) => ({
|
||||||
fontSize: theme.fontSizes.smallerBody,
|
fontSize: theme.fontSizes.smallerBody,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledLink = styled(Link, {
|
|
||||||
shouldForwardProp: prop => prop !== 'highlighted',
|
|
||||||
})<{ highlighted?: boolean }>(({ theme, highlighted }) => ({
|
|
||||||
backgroundColor: highlighted ? theme.palette.highlight : 'transparent',
|
|
||||||
}));
|
|
||||||
|
|
||||||
interface IFeatureTagCellProps {
|
interface IFeatureTagCellProps {
|
||||||
row: {
|
row: {
|
||||||
original: FeatureSchema;
|
original: FeatureSchema;
|
||||||
@ -31,8 +25,12 @@ export const FeatureTagCell: VFC<IFeatureTagCellProps> = ({ row, value }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TextCell>
|
<TextCell>
|
||||||
<HtmlTooltip
|
<TooltipLink
|
||||||
title={
|
highlighted={
|
||||||
|
searchQuery.length > 0 &&
|
||||||
|
value.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
|
}
|
||||||
|
tooltip={
|
||||||
<>
|
<>
|
||||||
{row.original.tags?.map(tag => (
|
{row.original.tags?.map(tag => (
|
||||||
<StyledTag key={tag.type + tag.value}>
|
<StyledTag key={tag.type + tag.value}>
|
||||||
@ -44,18 +42,10 @@ export const FeatureTagCell: VFC<IFeatureTagCellProps> = ({ row, value }) => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<StyledLink
|
{row.original.tags?.length === 1
|
||||||
underline="always"
|
? '1 tag'
|
||||||
highlighted={
|
: `${row.original.tags?.length} tags`}
|
||||||
searchQuery.length > 0 &&
|
</TooltipLink>
|
||||||
value.toLowerCase().includes(searchQuery.toLowerCase())
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{row.original.tags?.length === 1
|
|
||||||
? '1 tag'
|
|
||||||
: `${row.original.tags?.length} tags`}
|
|
||||||
</StyledLink>
|
|
||||||
</HtmlTooltip>
|
|
||||||
</TextCell>
|
</TextCell>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
34
frontend/src/component/common/TooltipLink/TooltipLink.tsx
Normal file
34
frontend/src/component/common/TooltipLink/TooltipLink.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { ReactNode } from 'react';
|
||||||
|
import { Link, LinkProps, styled, TooltipProps } from '@mui/material';
|
||||||
|
import { HtmlTooltip, IHtmlTooltipProps } from '../HtmlTooltip/HtmlTooltip';
|
||||||
|
|
||||||
|
const StyledLink = styled(Link, {
|
||||||
|
shouldForwardProp: prop => prop !== 'highlighted',
|
||||||
|
})<{ highlighted?: boolean }>(({ theme, highlighted }) => ({
|
||||||
|
backgroundColor: highlighted ? theme.palette.highlight : 'transparent',
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
textDecorationColor: theme.palette.text.disabled,
|
||||||
|
textDecorationStyle: 'dashed',
|
||||||
|
textUnderlineOffset: theme.spacing(0.5),
|
||||||
|
}));
|
||||||
|
|
||||||
|
interface ITooltipLinkProps extends LinkProps {
|
||||||
|
tooltip: ReactNode;
|
||||||
|
highlighted?: boolean;
|
||||||
|
tooltipProps?: Omit<IHtmlTooltipProps, 'title' | 'children'>;
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TooltipLink = ({
|
||||||
|
tooltip,
|
||||||
|
highlighted,
|
||||||
|
tooltipProps,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: ITooltipLinkProps) => (
|
||||||
|
<HtmlTooltip title={tooltip} {...tooltipProps}>
|
||||||
|
<StyledLink highlighted={highlighted} {...props}>
|
||||||
|
{children}
|
||||||
|
</StyledLink>
|
||||||
|
</HtmlTooltip>
|
||||||
|
);
|
@ -1,20 +1,14 @@
|
|||||||
import { Link, styled, Typography } from '@mui/material';
|
import { styled, Typography } from '@mui/material';
|
||||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
||||||
import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip';
|
|
||||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
||||||
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
||||||
|
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
|
||||||
import { IOverride } from 'interfaces/featureToggle';
|
import { IOverride } from 'interfaces/featureToggle';
|
||||||
|
|
||||||
const StyledItem = styled(Typography)(({ theme }) => ({
|
const StyledItem = styled(Typography)(({ theme }) => ({
|
||||||
fontSize: theme.fontSizes.smallerBody,
|
fontSize: theme.fontSizes.smallerBody,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledLink = styled(Link, {
|
|
||||||
shouldForwardProp: prop => prop !== 'highlighted',
|
|
||||||
})<{ highlighted?: boolean }>(({ theme, highlighted }) => ({
|
|
||||||
backgroundColor: highlighted ? theme.palette.highlight : 'transparent',
|
|
||||||
}));
|
|
||||||
|
|
||||||
interface IOverridesCellProps {
|
interface IOverridesCellProps {
|
||||||
value?: IOverride[];
|
value?: IOverride[];
|
||||||
}
|
}
|
||||||
@ -29,8 +23,8 @@ export const OverridesCell = ({ value: overrides }: IOverridesCellProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TextCell>
|
<TextCell>
|
||||||
<HtmlTooltip
|
<TooltipLink
|
||||||
title={
|
tooltip={
|
||||||
<>
|
<>
|
||||||
{overrides.map((override, index) => (
|
{overrides.map((override, index) => (
|
||||||
<StyledItem key={override.contextName + index}>
|
<StyledItem key={override.contextName + index}>
|
||||||
@ -41,23 +35,19 @@ export const OverridesCell = ({ value: overrides }: IOverridesCellProps) => {
|
|||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
highlighted={
|
||||||
|
searchQuery.length > 0 &&
|
||||||
|
overrides
|
||||||
|
?.map(overrideToString)
|
||||||
|
.join('\n')
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchQuery.toLowerCase())
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<StyledLink
|
{overrides.length === 1
|
||||||
underline="always"
|
? '1 override'
|
||||||
highlighted={
|
: `${overrides.length} overrides`}
|
||||||
searchQuery.length > 0 &&
|
</TooltipLink>
|
||||||
overrides
|
|
||||||
?.map(overrideToString)
|
|
||||||
.join('\n')
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(searchQuery.toLowerCase())
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{overrides.length === 1
|
|
||||||
? '1 override'
|
|
||||||
: `${overrides.length} overrides`}
|
|
||||||
</StyledLink>
|
|
||||||
</HtmlTooltip>
|
|
||||||
</TextCell>
|
</TextCell>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Link, styled, Typography } from '@mui/material';
|
import { styled, Typography } from '@mui/material';
|
||||||
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
import { Highlighter } from 'component/common/Highlighter/Highlighter';
|
||||||
import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip';
|
|
||||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
||||||
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
|
||||||
|
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
|
||||||
import { IPayload } from 'interfaces/featureToggle';
|
import { IPayload } from 'interfaces/featureToggle';
|
||||||
|
|
||||||
const StyledItem = styled(Typography)(({ theme }) => ({
|
const StyledItem = styled(Typography)(({ theme }) => ({
|
||||||
@ -10,12 +10,6 @@ const StyledItem = styled(Typography)(({ theme }) => ({
|
|||||||
whiteSpace: 'pre-wrap',
|
whiteSpace: 'pre-wrap',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledLink = styled(Link, {
|
|
||||||
shouldForwardProp: prop => prop !== 'highlighted',
|
|
||||||
})<{ highlighted?: boolean }>(({ theme, highlighted }) => ({
|
|
||||||
backgroundColor: highlighted ? theme.palette.highlight : 'transparent',
|
|
||||||
}));
|
|
||||||
|
|
||||||
interface IPayloadCellProps {
|
interface IPayloadCellProps {
|
||||||
value?: IPayload;
|
value?: IPayload;
|
||||||
}
|
}
|
||||||
@ -35,8 +29,8 @@ export const PayloadCell = ({ value: payload }: IPayloadCellProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TextCell>
|
<TextCell>
|
||||||
<HtmlTooltip
|
<TooltipLink
|
||||||
title={
|
tooltip={
|
||||||
<>
|
<>
|
||||||
<StyledItem>
|
<StyledItem>
|
||||||
<Highlighter search={searchQuery}>
|
<Highlighter search={searchQuery}>
|
||||||
@ -45,19 +39,15 @@ export const PayloadCell = ({ value: payload }: IPayloadCellProps) => {
|
|||||||
</StyledItem>
|
</StyledItem>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
highlighted={
|
||||||
|
searchQuery.length > 0 &&
|
||||||
|
payload.value
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchQuery.toLowerCase())
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<StyledLink
|
{payload.type}
|
||||||
underline="always"
|
</TooltipLink>
|
||||||
highlighted={
|
|
||||||
searchQuery.length > 0 &&
|
|
||||||
payload.value
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(searchQuery.toLowerCase())
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{payload.type}
|
|
||||||
</StyledLink>
|
|
||||||
</HtmlTooltip>
|
|
||||||
</TextCell>
|
</TextCell>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -8,12 +8,19 @@ export const ProjectRoleDescriptionEnvironmentPermissions = ({
|
|||||||
permissions,
|
permissions,
|
||||||
}: IProjectRoleDescriptionEnvironmentPermissionsProps) => (
|
}: IProjectRoleDescriptionEnvironmentPermissionsProps) => (
|
||||||
<>
|
<>
|
||||||
{permissions
|
{[
|
||||||
.filter((permission: any) => permission.environment === environment)
|
...new Set(
|
||||||
.map((permission: any) => permission.displayName)
|
permissions
|
||||||
|
.filter(
|
||||||
|
(permission: any) =>
|
||||||
|
permission.environment === environment
|
||||||
|
)
|
||||||
|
.map((permission: any) => permission.displayName)
|
||||||
|
),
|
||||||
|
]
|
||||||
.sort()
|
.sort()
|
||||||
.map((permission: any) => (
|
.map((permission: any) => (
|
||||||
<p key={permission}>{permission}</p>
|
<p key={`${environment}-${permission}`}>{permission}</p>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,19 +1,7 @@
|
|||||||
import { Link, Popover, styled } from '@mui/material';
|
|
||||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
||||||
import React from 'react';
|
|
||||||
import { VFC } from 'react';
|
import { VFC } from 'react';
|
||||||
import { ProjectRoleDescription } from 'component/project/ProjectAccess/ProjectAccessAssign/ProjectRoleDescription/ProjectRoleDescription';
|
import { ProjectRoleDescription } from 'component/project/ProjectAccess/ProjectAccessAssign/ProjectRoleDescription/ProjectRoleDescription';
|
||||||
|
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
|
||||||
const StyledLink = styled(Link)(() => ({
|
|
||||||
textDecoration: 'none',
|
|
||||||
'&:hover, &:focus': {
|
|
||||||
textDecoration: 'underline',
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledPopover = styled(Popover)(() => ({
|
|
||||||
pointerEvents: 'none',
|
|
||||||
}));
|
|
||||||
|
|
||||||
interface IProjectAccessRoleCellProps {
|
interface IProjectAccessRoleCellProps {
|
||||||
roleId: number;
|
roleId: number;
|
||||||
@ -28,49 +16,25 @@ export const ProjectAccessRoleCell: VFC<IProjectAccessRoleCellProps> = ({
|
|||||||
value,
|
value,
|
||||||
emptyText,
|
emptyText,
|
||||||
}) => {
|
}) => {
|
||||||
const [anchorEl, setAnchorEl] = React.useState<HTMLElement | null>(null);
|
|
||||||
|
|
||||||
const onPopoverOpen = (event: React.MouseEvent<HTMLElement>) => {
|
|
||||||
setAnchorEl(event.currentTarget);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onPopoverClose = () => {
|
|
||||||
setAnchorEl(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!value) return <TextCell>{emptyText}</TextCell>;
|
if (!value) return <TextCell>{emptyText}</TextCell>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<TextCell>
|
||||||
<TextCell>
|
<TooltipLink
|
||||||
<StyledLink
|
tooltip={
|
||||||
onMouseEnter={event => {
|
<ProjectRoleDescription
|
||||||
onPopoverOpen(event);
|
roleId={roleId}
|
||||||
}}
|
projectId={projectId}
|
||||||
onMouseLeave={onPopoverClose}
|
popover
|
||||||
>
|
/>
|
||||||
{value}
|
}
|
||||||
</StyledLink>
|
tooltipProps={{
|
||||||
</TextCell>
|
maxWidth: 500,
|
||||||
<StyledPopover
|
maxHeight: 600,
|
||||||
open={Boolean(anchorEl)}
|
|
||||||
anchorEl={anchorEl}
|
|
||||||
onClose={onPopoverClose}
|
|
||||||
anchorOrigin={{
|
|
||||||
vertical: 'bottom',
|
|
||||||
horizontal: 'left',
|
|
||||||
}}
|
|
||||||
transformOrigin={{
|
|
||||||
vertical: 'top',
|
|
||||||
horizontal: 'left',
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ProjectRoleDescription
|
{value}
|
||||||
roleId={roleId}
|
</TooltipLink>
|
||||||
projectId={projectId}
|
</TextCell>
|
||||||
popover
|
|
||||||
/>
|
|
||||||
</StyledPopover>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user