Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPDX-7987 Merge Contacts #959

Merged
merged 14 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/GlobalStyles/GlobalStyles.tsx
caleballdrin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const useStyles = makeStyles(() =>
'-moz-osx-font-smoothing': 'grayscale',
height: '100%',
width: '100%',
overflow: 'hidden',
},
body: {
height: '100%',
minHeight: '100vh',
width: '100%',
},
'#__next': {
Expand Down
2 changes: 0 additions & 2 deletions src/components/Layouts/Primary/Primary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@ const RootContainer = styled('div')(({ theme }) => ({

const ContentContainer = styled('div')(() => ({
display: 'flex',
overflow: 'hidden',
}));

const Content = styled('div')(() => ({
flex: '1 1 auto',
height: '100%',
overflow: 'auto',
}));

interface Props {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
CardHeader,
Grid,
IconButton,
Link,
Tooltip,
Typography,
useMediaQuery,
Expand Down Expand Up @@ -88,6 +89,7 @@
selected: boolean;
loser: boolean;
t: TFunction;
setContactFocus: SetContactFocus;
}
const ContactItem: React.FC<ContactItemProps> = ({
contact,
Expand All @@ -96,6 +98,7 @@
loser,
t,
side,
setContactFocus,
}) => {
const useStyles = makeStyles()(() => ({
contactBasic: {
Expand Down Expand Up @@ -144,6 +147,9 @@
}));
const { classes } = useStyles();
const locale = useLocale();
const handleContactNameClick = (contactId) => {
setContactFocus(contactId);
};
return (
<Card
className={`
Expand All @@ -166,7 +172,12 @@
}
title={
<>
<Typography variant="subtitle1">{contact.name}</Typography>{' '}
<Link
underline="hover"
onClick={() => handleContactNameClick(contact.id)}
>
<Typography variant="subtitle1">{contact.name}</Typography>
</Link>{' '}
{selected && (
<Typography variant="body2" className={classes.selected}>
{t('Use this one')}
Expand All @@ -182,13 +193,11 @@
className={classes.minimalPadding}
/>
<CardContent className={classes.minimalPadding}>
{contact.primaryAddress ? (
{contact.primaryAddress && (
<Typography variant="body2">
{`${contact?.primaryAddress?.street}
${contact?.primaryAddress?.city}, ${contact?.primaryAddress?.state} ${contact?.primaryAddress?.postalCode}`}
</Typography>
) : (
''
)}
<Typography variant="body2">
<Trans
Expand Down Expand Up @@ -216,13 +225,15 @@
contact1: RecordInfoFragment;
contact2: RecordInfoFragment;
update: (id1: string, id2: string, action: string) => void;
updating: boolean;
setContactFocus: SetContactFocus;
}

const Contact: React.FC<Props> = ({
const ContactPair: React.FC<Props> = ({
contact1,
contact2,
update,
updating,
setContactFocus,
}) => {
const [selected, setSelected] = useState('none');
Expand All @@ -233,29 +244,27 @@
const rightSelected = selected === 'right';

const updateState = (side: string): void => {
switch (side) {
case 'left':
setSelected('left');
update(contact1.id, contact2.id, 'merge');
break;
case 'right':
setSelected('right');
update(contact2.id, contact1.id, 'merge');
break;
case 'cancel':
setSelected('cancel');
update(contact1.id, contact2.id, 'cancel');
break;
default:
setSelected('');
update(contact1.id, contact2.id, 'cancel');
if (!updating) {
switch (side) {
case 'left':
setSelected('left');
update(contact1.id, contact2.id, 'merge');
break;

Check warning on line 252 in src/components/Tool/MergeContacts/ContactPair.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/Tool/MergeContacts/ContactPair.tsx#L249-L252

Added lines #L249 - L252 were not covered by tests
case 'right':
setSelected('right');
update(contact2.id, contact1.id, 'merge');
break;
case 'cancel':
setSelected('cancel');
update(contact1.id, contact2.id, 'cancel');
break;
default:
setSelected('');
update(contact1.id, contact2.id, 'cancel');

Check warning on line 263 in src/components/Tool/MergeContacts/ContactPair.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/Tool/MergeContacts/ContactPair.tsx#L261-L263

Added lines #L261 - L263 were not covered by tests
}
}
};

const handleContactNameClick = (contactId) => {
setContactFocus(contactId);
};

return (
<Grid
container
Expand All @@ -278,6 +287,7 @@
updateState={updateState}
selected={leftSelected}
loser={rightSelected}
setContactFocus={setContactFocus}
/>
<IconWrapper>
<Tooltip
Expand All @@ -286,12 +296,13 @@
placement={matches ? undefined : 'top'}
>
<IconButton
onClick={() => updateState('left')}

Check warning on line 299 in src/components/Tool/MergeContacts/ContactPair.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/Tool/MergeContacts/ContactPair.tsx#L299

Added line #L299 was not covered by tests
className={leftSelected ? classes.green : classes.grey}
data-testid="leftButton"
>
<Icon
path={matches ? mdiArrowUpBold : mdiArrowLeftBold}
size={1.5}
size={1}
/>
</IconButton>
</Tooltip>
Expand All @@ -303,10 +314,11 @@
<IconButton
onClick={() => updateState('right')}
className={rightSelected ? classes.green : classes.grey}
data-testid="rightButton"
>
<Icon
path={matches ? mdiArrowDownBold : mdiArrowRightBold}
size={1.5}
size={1}
/>
</IconButton>
</Tooltip>
Expand All @@ -316,8 +328,9 @@
className={
selected === 'cancel' ? classes.red : classes.grey
}
data-testid="ignoreButton"
>
<Icon path={mdiCloseThick} size={1.5} />
<Icon path={mdiCloseThick} size={1} />
</IconButton>
</Tooltip>
</IconWrapper>
Expand All @@ -328,6 +341,7 @@
updateState={updateState}
selected={rightSelected}
loser={leftSelected}
setContactFocus={setContactFocus}
/>
</Box>
</Grid>
Expand All @@ -338,4 +352,4 @@
);
};

export default Contact;
export default ContactPair;
32 changes: 28 additions & 4 deletions src/components/Tool/MergeContacts/MergeContacts.test.tsx
caleballdrin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import MergeContacts from './MergeContacts';

const accountListId = '123';

const setContactFocus = jest.fn();

const mocks = {
GetContactDuplicates: {
contactDuplicates: {
Expand Down Expand Up @@ -128,7 +130,10 @@ const MergeContactsWrapper: React.FC<MergeContactsWrapperProps> = ({
contactId={[]}
searchTerm={''}
>
<MergeContacts accountListId={accountListId} />
<MergeContacts
accountListId={accountListId}
setContactFocus={setContactFocus}
/>
</ContactsProvider>
</GqlMockedProvider>
</TestRouter>
Expand Down Expand Up @@ -186,8 +191,27 @@ describe('Tools - MergeContacts', () => {
],
},
});
// await waitFor(() =>
// expect(queryByText('Doe, John and Nancy')).not.toBeInTheDocument(),
// );
});

it('should ignore contacts', async () => {
const mutationSpy = jest.fn();

const { queryByText, queryAllByTestId, findByText, getByRole } = render(
<SnackbarProvider>
<MergeContactsWrapper mutationSpy={mutationSpy} />
</SnackbarProvider>,
);

await waitFor(() =>
expect(queryAllByTestId('MergeContactPair')).toHaveLength(2),
);
const confirmButton = getByRole('button', { name: 'Confirm and Continue' });

expect(confirmButton).toBeDisabled();
userEvent.click(queryAllByTestId('rightButton')[0]);
expect(await findByText('Use this one')).toBeInTheDocument();
userEvent.click(queryAllByTestId('ignoreButton')[0]);
expect(queryByText('Use this one')).not.toBeInTheDocument();
expect(confirmButton).not.toBeDisabled();
});
});
51 changes: 31 additions & 20 deletions src/components/Tool/MergeContacts/MergeContacts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@
import { useSnackbar } from 'notistack';
import { Trans, useTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper';
import { useMassActionsMergeMutation } from 'src/components/Contacts/MassActions/Merge/MassActionsMerge.generated';
import { LoadingSpinner } from 'src/components/Settings/Organization/LoadingSpinner';
import useGetAppSettings from 'src/hooks/useGetAppSettings';
import theme from '../../../theme';
import NoData from '../NoData';
import Contact from './Contact';
import ContactPair from './ContactPair';
import { useGetContactDuplicatesQuery } from './GetContactDuplicates.generated';

const useStyles = makeStyles()(() => ({
container: {
padding: theme.spacing(3),
width: '80%',
display: 'flex',
height: '100dvh',
height: 'auto',
[theme.breakpoints.down('lg')]: {
width: '100%',
},
Expand Down Expand Up @@ -57,13 +59,14 @@
paddingBottom: theme.spacing(2),
marginBottom: theme.spacing(2),
position: 'sticky',
top: '0',
top: '64px',
zIndex: '100',
borderBottom: '1px solid',
borderBottomColor: theme.palette.cruGrayLight.main,
[theme.breakpoints.down('sm')]: {
flexDirection: 'column',
alignItems: 'start',
top: '56px',
},
}));

Expand Down Expand Up @@ -99,28 +102,31 @@
const showing = data?.contactDuplicates.nodes.length || 0;

const updateActions = (id1: string, id2: string, action: string): void => {
if (action === 'cancel') {
setActions((prevState) => ({
...prevState,
[id1]: { action: '' },
[id2]: { action: '' },
}));
} else {
setActions((prevState) => ({
...prevState,
[id1]: { action: 'merge', mergeId: id2 },
[id2]: { action: 'delete' },
}));
if (!updating) {
if (action === 'cancel') {
setActions((prevState) => ({
...prevState,
[id1]: { action: '' },
[id2]: { action: '' },
}));
} else {
setActions((prevState) => ({
...prevState,
[id1]: { action: 'merge', mergeId: id2 },
[id2]: { action: 'delete' },
}));
}
}
};
const handleConfirmAndContinue = async () => {
await mergeContacts();
setActions({});
};
const handleConfirmAndLeave = async () => {
await mergeContacts().then(
() =>
(window.location.href = `${process.env.SITE_URL}/accountLists/${accountListId}/tools`),
);
await mergeContacts().then(() => {
window.location.href = `${process.env.SITE_URL}/accountLists/${accountListId}/tools`;
setActions({});

Check warning on line 128 in src/components/Tool/MergeContacts/MergeContacts.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/Tool/MergeContacts/MergeContacts.tsx#L126-L128

Added lines #L126 - L128 were not covered by tests
});
};

const mergeContacts = async () => {
Expand Down Expand Up @@ -150,8 +156,8 @@
variant: 'success',
});
},
onError: (err) => {
enqueueSnackbar(t('A server error occurred. {{err}}', { err }), {

Check warning on line 160 in src/components/Tool/MergeContacts/MergeContacts.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/Tool/MergeContacts/MergeContacts.tsx#L159-L160

Added lines #L159 - L160 were not covered by tests
variant: 'error',
});
},
Expand All @@ -166,6 +172,9 @@
flexDirection="column"
data-testid="Home"
>
{(loading || updating) && (
<LoadingSpinner firstLoad={true} data-testid="LoadingSpinner" />
)}
{!loading && data ? (
<Grid container className={classes.container}>
<Grid item xs={12}>
Expand Down Expand Up @@ -221,7 +230,7 @@
<Button
variant="contained"
disabled={disabled}
onClick={() => handleConfirmAndLeave()}

Check warning on line 233 in src/components/Tool/MergeContacts/MergeContacts.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/Tool/MergeContacts/MergeContacts.tsx#L233

Added line #L233 was not covered by tests
>
{t('Confirm and Leave')}
</Button>
Expand All @@ -230,11 +239,13 @@
<Grid item xs={12} sx={{ margin: '0px 2px 20px 2px' }}>
{data?.contactDuplicates.nodes
.map((duplicate) => (
<Contact
<ContactPair
key={duplicate.id}
contact1={duplicate.recordOne}
contact2={duplicate.recordTwo}
update={updateActions}
updating={updating}
setContactFocus={setContactFocus}
/>
))
.reverse()}
Expand Down
Loading