Skip to content

Commit 2efc791

Browse files
committed
fix(cozy-sharing): Avoid rendering email twice in recipient row
When a recipient has no public_name or name field, getDisplayName falls back to the email for the primary text. The secondary text rendered by MemberRecipientStatus was also showing the email, producing a duplicate. Pass the raw recipient name through a new optional prop so MemberRecipientStatus can suppress the email in the secondary text when it would duplicate the primary, while still showing the instance when there is no email at all.
1 parent 391ec73 commit 2efc791

5 files changed

Lines changed: 107 additions & 1 deletion

File tree

packages/cozy-sharing/src/components/Recipient/GroupRecipientDetailWithAccess.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const GroupRecipientDetailWithAccess = ({ withAccess }) => {
3939
isMe={isMe}
4040
instance={recipient.instance}
4141
email={recipient.email}
42+
name={recipient.name || recipient.public_name}
4243
/>
4344
}
4445
/>

packages/cozy-sharing/src/components/Recipient/MemberRecipient.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ const MemberRecipient = props => {
6767
isMe={isMe}
6868
instance={instance}
6969
email={rest.email}
70+
name={rest.name || rest.public_name}
7071
/>
7172
}
7273
/>

packages/cozy-sharing/src/components/Recipient/MemberRecipientLite.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const MemberRecipientLite = ({ recipient, isOwner, ...props }) => {
3939
isMe={isMe}
4040
instance={recipient.instance}
4141
email={recipient.email}
42+
name={recipient.name || recipient.public_name}
4243
typographyProps={{ noWrap: true }}
4344
/>
4445
}

packages/cozy-sharing/src/components/Recipient/MemberRecipientStatus.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const MemberRecipientStatus = ({
99
isMe,
1010
instance,
1111
email,
12+
name,
1213
typographyProps
1314
}) => {
1415
const { t } = useI18n()
@@ -17,7 +18,11 @@ const MemberRecipientStatus = ({
1718
const isReady = isMe || status === 'ready' || status === 'owner'
1819
let text
1920
if (isReady) {
20-
text = email || instance
21+
// Hide the email when the parent already uses it as the primary text
22+
// (getDisplayName falls back to email when the recipient has no name).
23+
// Keep the instance visible when there is no email at all, so the user
24+
// can still tell the recipient lives on a different Cozy instance.
25+
text = isMe || name || !email ? email || instance : ''
2126
} else if (isSendingEmail) {
2227
text = t('Share.status.mail-not-sent')
2328
} else {
@@ -39,6 +44,7 @@ MemberRecipientStatus.propTypes = {
3944
isMe: PropTypes.bool,
4045
instance: PropTypes.string,
4146
email: PropTypes.string,
47+
name: PropTypes.string,
4248
typographyProps: PropTypes.object
4349
}
4450

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { render } from '@testing-library/react'
2+
import React from 'react'
3+
4+
import MemberRecipientStatus from './MemberRecipientStatus'
5+
import AppLike from '../../../test/AppLike'
6+
7+
describe('MemberRecipientStatus component', () => {
8+
const setup = props =>
9+
render(
10+
<AppLike>
11+
<MemberRecipientStatus {...props} />
12+
</AppLike>
13+
)
14+
15+
it('should show email when status is ready and recipient has a name', () => {
16+
const { getByText } = setup({
17+
status: 'ready',
18+
isMe: false,
19+
email: 'other@example.com',
20+
instance: 'foo.mycozy.cloud',
21+
name: 'Other Person'
22+
})
23+
expect(getByText('other@example.com')).toBeTruthy()
24+
})
25+
26+
it('should render nothing when recipient has no name and status is ready', () => {
27+
const { queryByText } = setup({
28+
status: 'ready',
29+
isMe: false,
30+
email: 'other@example.com',
31+
instance: 'foo.mycozy.cloud'
32+
})
33+
expect(queryByText('other@example.com')).toBe(null)
34+
expect(queryByText('foo.mycozy.cloud')).toBe(null)
35+
})
36+
37+
it('should show email when isMe is true regardless of status', () => {
38+
const { getByText } = setup({
39+
status: 'pending',
40+
isMe: true,
41+
email: 'me@example.com'
42+
})
43+
expect(getByText('me@example.com')).toBeTruthy()
44+
})
45+
46+
it('should fallback to instance when email is missing and status is ready', () => {
47+
const { getByText } = setup({
48+
status: 'ready',
49+
isMe: false,
50+
instance: 'foo.mycozy.cloud'
51+
})
52+
expect(getByText('foo.mycozy.cloud')).toBeTruthy()
53+
})
54+
55+
it('should show email when status is owner, not isMe, and recipient has a name', () => {
56+
const { getByText } = setup({
57+
status: 'owner',
58+
isMe: false,
59+
email: 'owner@example.com',
60+
instance: 'foo.mycozy.cloud',
61+
name: 'Owner Person'
62+
})
63+
expect(getByText('owner@example.com')).toBeTruthy()
64+
})
65+
66+
it('should show "Sending invitation mail..." when status is mail-not-sent and not isMe', () => {
67+
const { getByText } = setup({
68+
status: 'mail-not-sent',
69+
isMe: false
70+
})
71+
expect(getByText('Sending invitation mail...')).toBeTruthy()
72+
})
73+
74+
it('should show "Invitation sent" when status is pending', () => {
75+
const { getByText } = setup({
76+
status: 'pending',
77+
isMe: false
78+
})
79+
expect(getByText('Invitation sent')).toBeTruthy()
80+
})
81+
82+
it('should show "Invitation seen" when status is seen', () => {
83+
const { getByText } = setup({
84+
status: 'seen',
85+
isMe: false
86+
})
87+
expect(getByText('Invitation seen')).toBeTruthy()
88+
})
89+
90+
it('should fallback to "Invitation sent" for unknown status', () => {
91+
const { getByText } = setup({
92+
status: 'unknown-status',
93+
isMe: false
94+
})
95+
expect(getByText('Invitation sent')).toBeTruthy()
96+
})
97+
})

0 commit comments

Comments
 (0)