Ej/fix message visibility (#11874)

<img width="257" alt="Screenshot 2025-05-05 at 15 30 09"
src="https://github.com/user-attachments/assets/5a8e18e0-efc5-4521-9c3a-bf73277ecdf9"
/>
<img width="257" alt="Screenshot 2025-05-05 at 15 29 05"
src="https://github.com/user-attachments/assets/c1a784af-a744-497a-b6ce-ec3a9e8b851a"
/>
<img width="257" alt="Screenshot 2025-05-05 at 15 33 06"
src="https://github.com/user-attachments/assets/c5fabd1d-a125-49d7-aade-0a208a0eff95"
/>

related to PR https://github.com/twentyhq/twenty/pull/11840 and issue
https://github.com/twentyhq/twenty/issues/9826
This commit is contained in:
Etienne
2025-05-05 17:23:27 +02:00
committed by GitHub
parent da0c7e679e
commit a60711c808
19 changed files with 578 additions and 481 deletions

View File

@ -1,11 +1,12 @@
import styled from '@emotion/styled';
import { isUndefined } from '@sniptt/guards';
import { EmailThreadMessage } from '@/activities/emails/types/EmailThreadMessage';
import { EventCardMessageNotShared } from '@/activities/timeline-activities/rows/message/components/EventCardMessageNotShared';
import { EventCardMessageBodyNotShared } from '@/activities/timeline-activities/rows/message/components/EventCardMessageBodyNotShared';
import { EventCardMessageForbidden } from '@/activities/timeline-activities/rows/message/components/EventCardMessageForbidden';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
import { FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED } from 'twenty-shared/constants';
import { isDefined } from 'twenty-shared/utils';
import { OverflowingTextWithTooltip } from 'twenty-ui/display';
@ -85,7 +86,7 @@ export const EventCardMessage = ({
);
if (shouldHideMessageContent) {
return <EventCardMessageNotShared sharedByFullName={authorFullName} />;
return <EventCardMessageForbidden notSharedByFullName={authorFullName} />;
}
const shouldHandleNotFound = error.graphQLErrors.some(
@ -99,7 +100,7 @@ export const EventCardMessage = ({
return <div>Error loading message</div>;
}
if (loading || isUndefined(message)) {
if (loading || !isDefined(message)) {
return <div>Loading...</div>;
}
@ -112,12 +113,21 @@ export const EventCardMessage = ({
<StyledEventCardMessageContainer>
<StyledEmailContent>
<StyledEmailTop>
<StyledEmailTitle>{message.subject}</StyledEmailTitle>
<StyledEmailTitle>
{message.subject !==
FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED
? message.subject
: 'Subject not shared'}
</StyledEmailTitle>
<StyledEmailParticipants>
<OverflowingTextWithTooltip text={messageParticipantHandles} />
</StyledEmailParticipants>
</StyledEmailTop>
<StyledEmailBody>{message.text}</StyledEmailBody>
{message.text !== FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED ? (
<StyledEmailBody>{message.text}</StyledEmailBody>
) : (
<EventCardMessageBodyNotShared notSharedByFullName={authorFullName} />
)}
</StyledEmailContent>
</StyledEventCardMessageContainer>
);

View File

@ -0,0 +1,51 @@
import styled from '@emotion/styled';
import { IconLock } from 'twenty-ui/display';
const StyledEmailBodyNotSharedContainer = styled.div`
align-items: center;
background: ${({ theme }) => theme.background.transparent.lighter};
border: 1px solid ${({ theme }) => theme.border.color.light};
border-radius: ${({ theme }) => theme.spacing(1)};
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(3)};
height: 80px;
justify-content: center;
color: ${({ theme }) => theme.font.color.light};
font-size: ${({ theme }) => theme.font.size.sm};
font-weight: ${({ theme }) => theme.font.weight.medium};
width: 100%;
`;
const StyledEmailBodyNotSharedIconContainer = styled.div`
display: flex;
width: ${({ theme }) => theme.icon.size.sm}px;
height: ${({ theme }) => theme.icon.size.sm}px;
justify-content: center;
align-items: center;
`;
const StyledEmailBodyNotShared = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
`;
export const EventCardMessageBodyNotShared = ({
notSharedByFullName,
}: {
notSharedByFullName: string;
}) => {
return (
<StyledEmailBodyNotSharedContainer>
<StyledEmailBodyNotShared>
<StyledEmailBodyNotSharedIconContainer>
<IconLock />
</StyledEmailBodyNotSharedIconContainer>
<span>Not shared by {notSharedByFullName}</span>
</StyledEmailBodyNotShared>
</StyledEmailBodyNotSharedContainer>
);
};

View File

@ -0,0 +1,43 @@
import { EventCardMessageBodyNotShared } from '@/activities/timeline-activities/rows/message/components/EventCardMessageBodyNotShared';
import styled from '@emotion/styled';
const StyledEventCardMessageContainer = styled.div`
display: flex;
flex-direction: column;
width: 100%;
`;
const StyledEmailContent = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(4)};
justify-content: center;
width: 100%;
`;
const StyledEmailTitle = styled.div`
color: ${({ theme }) => theme.font.color.primary};
font-weight: ${({ theme }) => theme.font.weight.medium};
display: flex;
flex-direction: column;
margin-top: ${({ theme }) => theme.spacing(2)};
`;
export const EventCardMessageForbidden = ({
notSharedByFullName,
}: {
notSharedByFullName: string;
}) => {
return (
<StyledEventCardMessageContainer>
<StyledEmailContent>
<StyledEmailTitle>
<span>Subject not shared</span>
</StyledEmailTitle>
<EventCardMessageBodyNotShared
notSharedByFullName={notSharedByFullName}
/>
</StyledEmailContent>
</StyledEventCardMessageContainer>
);
};

View File

@ -1,86 +0,0 @@
import styled from '@emotion/styled';
import { IconLock } from 'twenty-ui/display';
const StyledEventCardMessageContainer = styled.div`
display: flex;
flex-direction: column;
`;
const StyledEmailContent = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(4)};
justify-content: center;
`;
const StyledEmailTop = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
`;
const StyledEmailTitle = styled.div`
color: ${({ theme }) => theme.font.color.primary};
font-weight: ${({ theme }) => theme.font.weight.medium};
display: flex;
`;
const StyledEmailBodyNotShareContainer = styled.div`
align-items: center;
align-self: stretch;
background: ${({ theme }) => theme.background.transparent.lighter};
border: 1px solid ${({ theme }) => theme.border.color.light};
border-radius: ${({ theme }) => theme.spacing(1)};
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(3)};
height: 80px;
justify-content: center;
padding: 0 ${({ theme }) => theme.spacing(1)};
color: ${({ theme }) => theme.font.color.light};
font-size: ${({ theme }) => theme.font.size.sm};
font-weight: ${({ theme }) => theme.font.weight.medium};
`;
const StyledEmailBodyNotSharedIconContainer = styled.div`
display: flex;
width: 14px;
height: 14px;
justify-content: center;
align-items: center;
`;
const StyledEmailBodyNotShare = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
padding: 0 ${({ theme }) => theme.spacing(1)};
`;
export const EventCardMessageNotShared = ({
sharedByFullName,
}: {
sharedByFullName: string;
}) => {
return (
<StyledEventCardMessageContainer>
<StyledEmailContent>
<StyledEmailTop>
<StyledEmailTitle>
<span>Subject not shared</span>
</StyledEmailTitle>
</StyledEmailTop>
<StyledEmailBodyNotShareContainer>
<StyledEmailBodyNotShare>
<StyledEmailBodyNotSharedIconContainer>
<IconLock />
</StyledEmailBodyNotSharedIconContainer>
<span>Not shared by {sharedByFullName}</span>
</StyledEmailBodyNotShare>
</StyledEmailBodyNotShareContainer>
</StyledEmailContent>
</StyledEventCardMessageContainer>
);
};