fix/replace-set-primary-with-bookmark-12268 (#12276)

## 🛠️ What this PR fixes

Fixes #12268

This PR fixes the UI behavior where the "Set as Primary" button was
incorrectly shown for emails or phones that are already marked as
primary. Instead, users now see a bookmark icon indicating the entry as
primary.

## 🎥 Demo

The attached video demonstrates the updated UI where the "Set as
Primary" button is hidden for primary contacts or emails and replaced by
a bookmark icon.



https://github.com/user-attachments/assets/9afcc818-fbb4-4e7c-8fa2-093fdc7d8a26

---------

Co-authored-by: Davinder Kumar <davinder.kumar@intverse.io>
Co-authored-by: Devessier <baptiste@devessier.fr>
This commit is contained in:
Davinder Kumar
2025-05-27 14:40:12 +05:30
committed by GitHub
parent 92aa6a8e1a
commit 8cf3b83bb9
4 changed files with 28 additions and 50 deletions

View File

@ -45,7 +45,9 @@ export const EmailsFieldInput = ({
[], [],
); );
const isPrimaryEmail = (index: number) => index === 0 && emails?.length > 1; const getShowPrimaryIcon = (index: number) =>
index === 0 && emails.length > 1;
const getShowSetAsPrimaryButton = (index: number) => index > 0;
const setIsFieldInError = useSetRecoilComponentStateV2( const setIsFieldInError = useSetRecoilComponentStateV2(
recordFieldInputIsFieldInErrorComponentState, recordFieldInputIsFieldInErrorComponentState,
@ -77,8 +79,8 @@ export const EmailsFieldInput = ({
<EmailsFieldMenuItem <EmailsFieldMenuItem
key={index} key={index}
dropdownId={`emails-${index}`} dropdownId={`emails-${index}`}
showPrimaryIcon={isPrimaryEmail(index)} showPrimaryIcon={getShowPrimaryIcon(index)}
showSetAsPrimaryButton={!isPrimaryEmail(index)} showSetAsPrimaryButton={getShowSetAsPrimaryButton(index)}
email={email} email={email}
onEdit={handleEdit} onEdit={handleEdit}
onSetAsPrimary={handleSetPrimary} onSetAsPrimary={handleSetPrimary}

View File

@ -94,7 +94,9 @@ export const PhonesFieldInput = ({
}); });
}; };
const isPrimaryPhone = (index: number) => index === 0 && phones?.length > 1; const getShowPrimaryIcon = (index: number) =>
index === 0 && phones.length > 1;
const getShowSetAsPrimaryButton = (index: number) => index > 0;
return ( return (
<MultiItemFieldInput <MultiItemFieldInput
@ -129,8 +131,8 @@ export const PhonesFieldInput = ({
<PhonesFieldMenuItem <PhonesFieldMenuItem
key={index} key={index}
dropdownId={`phones-field-input-${fieldDefinition.metadata.fieldName}-${index}`} dropdownId={`phones-field-input-${fieldDefinition.metadata.fieldName}-${index}`}
showPrimaryIcon={isPrimaryPhone(index)} showPrimaryIcon={getShowPrimaryIcon(index)}
showSetAsPrimaryButton={!isPrimaryPhone(index)} showSetAsPrimaryButton={getShowSetAsPrimaryButton(index)}
phone={phone} phone={phone}
onEdit={handleEdit} onEdit={handleEdit}
onSetAsPrimary={handleSetPrimary} onSetAsPrimary={handleSetPrimary}

View File

@ -1,6 +1,6 @@
import { expect } from '@storybook/jest'; import { expect } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { fn, userEvent, waitFor, within } from '@storybook/test'; import { fn, userEvent, within } from '@storybook/test';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing'; import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing';
@ -132,7 +132,7 @@ export const Default: Story = {
}; };
// FIXME: We will have to fix that behavior, we should only be able to set a secondary email as the primary email // FIXME: We will have to fix that behavior, we should only be able to set a secondary email as the primary email
export const CanSetPrimaryLinkAsPrimaryLink: Story = { export const CanNotSetPrimaryLinkAsPrimaryLink: Story = {
args: { args: {
value: { value: {
primaryEmail: 'primary@example.com', primaryEmail: 'primary@example.com',
@ -152,28 +152,16 @@ export const CanSetPrimaryLinkAsPrimaryLink: Story = {
}); });
await userEvent.click(openDropdownButtons[0]); await userEvent.click(openDropdownButtons[0]);
const setPrimaryOption = await within( const editOption = await within(
getCanvasElementForDropdownTesting(), getCanvasElementForDropdownTesting(),
).findByText('Set as Primary'); ).findByText('Edit');
expect(setPrimaryOption).toBeVisible(); expect(editOption).toBeVisible();
await userEvent.click(setPrimaryOption); const setPrimaryOption = within(
getCanvasElementForDropdownTesting(),
).queryByText('Set as Primary');
// Verify the update was called with swapped emails expect(setPrimaryOption).not.toBeInTheDocument();
await waitFor(() => {
expect(updateRecord).toHaveBeenCalledWith({
variables: {
where: { id: 'record-id' },
updateOneRecordInput: {
emails: {
primaryEmail: 'primary@example.com',
additionalEmails: [],
},
},
},
});
});
expect(updateRecord).toHaveBeenCalledTimes(1);
}, },
}; };

View File

@ -1,6 +1,6 @@
import { expect } from '@storybook/jest'; import { expect } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { fn, userEvent, waitFor, within } from '@storybook/test'; import { fn, userEvent, within } from '@storybook/test';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing'; import { getCanvasElementForDropdownTesting } from 'twenty-ui/testing';
@ -141,7 +141,7 @@ export const Default: Story = {
}; };
// FIXME: We will have to fix that behavior, we should only be able to set an additional phone as the primary phone // FIXME: We will have to fix that behavior, we should only be able to set an additional phone as the primary phone
export const CanSetPrimaryLinkAsPrimaryLink: Story = { export const CanNotSetPrimaryLinkAsPrimaryLink: Story = {
args: { args: {
value: { value: {
primaryPhoneCountryCode: 'FR', primaryPhoneCountryCode: 'FR',
@ -163,30 +163,16 @@ export const CanSetPrimaryLinkAsPrimaryLink: Story = {
}); });
await userEvent.click(openDropdownButtons[0]); await userEvent.click(openDropdownButtons[0]);
const setPrimaryOption = await within( const editOption = await within(
getCanvasElementForDropdownTesting(), getCanvasElementForDropdownTesting(),
).findByText('Set as Primary'); ).findByText('Edit');
expect(setPrimaryOption).toBeVisible(); expect(editOption).toBeVisible();
await userEvent.click(setPrimaryOption); const setPrimaryOption = within(
getCanvasElementForDropdownTesting(),
).queryByText('Set as Primary');
// Verify the update was called with swapped phones expect(setPrimaryOption).not.toBeInTheDocument();
await waitFor(() => {
expect(updateRecord).toHaveBeenCalledWith({
variables: {
where: { id: 'record-id' },
updateOneRecordInput: {
phones: {
primaryPhoneCallingCode: '+33',
primaryPhoneCountryCode: 'FR',
primaryPhoneNumber: '642646272',
additionalPhones: [],
},
},
},
});
});
expect(updateRecord).toHaveBeenCalledTimes(1);
}, },
}; };