mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-23 20:13:21 +03:00
Issue: Long names in the Members table were overflowing, affecting the layout. Fix: - Trimmed long names with ellipses. - Added tooltips to display the full content on hover. - Max-width of the text dynamically set to 90px on large screens, and 60px on mobile. ![image](https://github.com/user-attachments/assets/3b5d1c08-fe0e-4c0b-952a-0fc0f9e513bc) --------- Co-authored-by: karankhatik <karan13699@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
parent
1e2c5bb8de
commit
1e6346febd
@ -1,6 +1,7 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import isPropValid from '@emotion/is-prop-valid';
|
||||
import styled from '@emotion/styled';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { MOBILE_VIEWPORT } from 'twenty-ui';
|
||||
|
||||
const StyledTableRow = styled('div', {
|
||||
shouldForwardProp: (prop) =>
|
||||
@ -10,12 +11,19 @@ const StyledTableRow = styled('div', {
|
||||
onClick?: () => void;
|
||||
to?: string;
|
||||
gridAutoColumns?: string;
|
||||
mobileGridAutoColumns?: string;
|
||||
}>`
|
||||
background-color: ${({ isSelected, theme }) =>
|
||||
isSelected ? theme.accent.quaternary : 'transparent'};
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
display: grid;
|
||||
grid-auto-columns: ${({ gridAutoColumns }) => gridAutoColumns ?? '1fr'};
|
||||
|
||||
@media (max-width: ${MOBILE_VIEWPORT}px) {
|
||||
grid-auto-columns: ${({ mobileGridAutoColumns, gridAutoColumns }) =>
|
||||
mobileGridAutoColumns ?? gridAutoColumns ?? '1fr'};
|
||||
}
|
||||
|
||||
grid-auto-flow: column;
|
||||
transition: background-color
|
||||
${({ theme }) => theme.animation.duration.normal}s;
|
||||
@ -35,6 +43,7 @@ type TableRowProps = {
|
||||
to?: string;
|
||||
className?: string;
|
||||
gridAutoColumns?: string;
|
||||
mobileGridAutoColumns?: string;
|
||||
};
|
||||
|
||||
export const TableRow = ({
|
||||
@ -44,12 +53,14 @@ export const TableRow = ({
|
||||
className,
|
||||
children,
|
||||
gridAutoColumns,
|
||||
mobileGridAutoColumns,
|
||||
}: React.PropsWithChildren<TableRowProps>) => (
|
||||
<StyledTableRow
|
||||
isSelected={isSelected}
|
||||
onClick={onClick}
|
||||
gridAutoColumns={gridAutoColumns}
|
||||
className={className}
|
||||
mobileGridAutoColumns={mobileGridAutoColumns}
|
||||
to={to}
|
||||
as={to ? Link : 'div'}
|
||||
>
|
||||
|
@ -4,12 +4,13 @@ import { isNonEmptyArray } from '@sniptt/guards';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import {
|
||||
AppTooltip,
|
||||
Avatar,
|
||||
H2Title,
|
||||
IconMail,
|
||||
IconReload,
|
||||
IconTrash,
|
||||
MOBILE_VIEWPORT,
|
||||
TooltipDelay,
|
||||
} from 'twenty-ui';
|
||||
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
@ -52,51 +53,22 @@ const StyledTable = styled(Table)`
|
||||
margin-top: ${({ theme }) => theme.spacing(0.5)};
|
||||
`;
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
@media (max-width: ${MOBILE_VIEWPORT}px) {
|
||||
display: grid;
|
||||
grid-template-columns: 3fr;
|
||||
}
|
||||
`;
|
||||
const StyledTableCell = styled(TableCell)`
|
||||
padding: ${({ theme }) => theme.spacing(1)};
|
||||
@media (max-width: ${MOBILE_VIEWPORT}px) {
|
||||
&:first-child {
|
||||
max-width: 100%;
|
||||
padding-top: 2px;
|
||||
white-space: nowrap;
|
||||
overflow: scroll;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
`;
|
||||
const StyledIconWrapper = styled.div`
|
||||
left: 2px;
|
||||
margin-right: ${({ theme }) => theme.spacing(2)};
|
||||
position: relative;
|
||||
top: 1px;
|
||||
`;
|
||||
|
||||
const StyledScrollableTextContainer = styled.div`
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
white-space: pre-line;
|
||||
`;
|
||||
|
||||
const StyledTextContainer = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
max-width: max-content;
|
||||
overflow-x: auto;
|
||||
position: absolute;
|
||||
@media (min-width: 360px) and (max-width: 420px) {
|
||||
max-width: 150px;
|
||||
margin-top: ${({ theme }) => theme.spacing(1)};
|
||||
}
|
||||
`;
|
||||
const StyledTableHeaderRow = styled(Table)`
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1.5)};
|
||||
`;
|
||||
|
||||
const StyledIconWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
const StyledTextContainerWithEllipsis = styled.div`
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
export const SettingsWorkspaceMembers = () => {
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
const theme = useTheme();
|
||||
@ -194,7 +166,10 @@ export const SettingsWorkspaceMembers = () => {
|
||||
/>
|
||||
<Table>
|
||||
<StyledTableHeaderRow>
|
||||
<TableRow>
|
||||
<TableRow
|
||||
gridAutoColumns="150px 1fr 1fr"
|
||||
mobileGridAutoColumns="100px 1fr 1fr"
|
||||
>
|
||||
<TableHeader>Name</TableHeader>
|
||||
<TableHeader>Email</TableHeader>
|
||||
<TableHeader align={'right'}></TableHeader>
|
||||
@ -202,7 +177,10 @@ export const SettingsWorkspaceMembers = () => {
|
||||
</StyledTableHeaderRow>
|
||||
{workspaceMembers?.map((workspaceMember) => (
|
||||
<StyledTable key={workspaceMember.id}>
|
||||
<TableRow>
|
||||
<TableRow
|
||||
gridAutoColumns="150px 1fr 1fr"
|
||||
mobileGridAutoColumns="100px 1fr 1fr"
|
||||
>
|
||||
<TableCell>
|
||||
<StyledIconWrapper>
|
||||
<Avatar
|
||||
@ -213,16 +191,26 @@ export const SettingsWorkspaceMembers = () => {
|
||||
size="sm"
|
||||
/>
|
||||
</StyledIconWrapper>
|
||||
<StyledScrollableTextContainer>
|
||||
<StyledTextContainerWithEllipsis
|
||||
id={`hover-text-${workspaceMember.id}`}
|
||||
>
|
||||
{workspaceMember.name.firstName +
|
||||
' ' +
|
||||
workspaceMember.name.lastName}
|
||||
</StyledScrollableTextContainer>
|
||||
</StyledTextContainerWithEllipsis>
|
||||
<AppTooltip
|
||||
anchorSelect={`#hover-text-${workspaceMember.id}`}
|
||||
content={`${workspaceMember.name.firstName} ${workspaceMember.name.lastName}`}
|
||||
noArrow
|
||||
place="top"
|
||||
positionStrategy="fixed"
|
||||
delay={TooltipDelay.shortDelay}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<StyledTextContainer>
|
||||
<StyledTextContainerWithEllipsis>
|
||||
{workspaceMember.userEmail}
|
||||
</StyledTextContainer>
|
||||
</StyledTextContainerWithEllipsis>
|
||||
</TableCell>
|
||||
<TableCell align={'right'}>
|
||||
{currentWorkspaceMember?.id !== workspaceMember.id && (
|
||||
@ -253,7 +241,10 @@ export const SettingsWorkspaceMembers = () => {
|
||||
{isNonEmptyArray(workspaceInvitations) && (
|
||||
<Table>
|
||||
<StyledTableHeaderRow>
|
||||
<TableRow gridAutoColumns={`1fr 1fr ${theme.spacing(22)}`}>
|
||||
<TableRow
|
||||
gridAutoColumns="150px 1fr 1fr"
|
||||
mobileGridAutoColumns="100px 1fr 1fr"
|
||||
>
|
||||
<TableHeader>Email</TableHeader>
|
||||
<TableHeader align={'right'}>Expires in</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
@ -261,27 +252,28 @@ export const SettingsWorkspaceMembers = () => {
|
||||
</StyledTableHeaderRow>
|
||||
{workspaceInvitations?.map((workspaceInvitation) => (
|
||||
<StyledTable key={workspaceInvitation.id}>
|
||||
<StyledTableRow
|
||||
gridAutoColumns={`1fr 1fr ${theme.spacing(22)}`}
|
||||
<TableRow
|
||||
gridAutoColumns="150px 1fr 1fr"
|
||||
mobileGridAutoColumns="100px 1fr 1fr"
|
||||
>
|
||||
<StyledTableCell>
|
||||
<TableCell>
|
||||
<StyledIconWrapper>
|
||||
<IconMail
|
||||
size={theme.icon.size.md}
|
||||
stroke={theme.icon.stroke.sm}
|
||||
/>
|
||||
</StyledIconWrapper>
|
||||
<StyledScrollableTextContainer>
|
||||
<StyledTextContainerWithEllipsis>
|
||||
{workspaceInvitation.email}
|
||||
</StyledScrollableTextContainer>
|
||||
</StyledTableCell>
|
||||
<StyledTableCell align={'right'}>
|
||||
</StyledTextContainerWithEllipsis>
|
||||
</TableCell>
|
||||
<TableCell align={'right'}>
|
||||
<Status
|
||||
color={'gray'}
|
||||
text={getExpiresAtText(workspaceInvitation.expiresAt)}
|
||||
/>
|
||||
</StyledTableCell>
|
||||
<StyledTableCell align={'right'}>
|
||||
</TableCell>
|
||||
<TableCell align={'right'}>
|
||||
<StyledButtonContainer>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
@ -304,8 +296,8 @@ export const SettingsWorkspaceMembers = () => {
|
||||
Icon={IconTrash}
|
||||
/>
|
||||
</StyledButtonContainer>
|
||||
</StyledTableCell>
|
||||
</StyledTableRow>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</StyledTable>
|
||||
))}
|
||||
</Table>
|
||||
|
Loading…
Reference in New Issue
Block a user