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

Contact import automation #2992

Merged
merged 40 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
4c0e0c8
first stab at contact import ui
akanshaaa19 Jul 23, 2024
d43bb62
upload contacts api
akanshaaa19 Jul 23, 2024
fae7127
Merge branch 'master' of github.com:glific/glific-frontend into featu…
akanshaaa19 Jul 23, 2024
5ab6226
added status
akanshaaa19 Jul 26, 2024
0f3e3ec
added support for downloading csv
akanshaaa19 Aug 8, 2024
c3dd29e
Merge branch 'master' of github.com:glific/glific-frontend into featu…
akanshaaa19 Aug 8, 2024
dd6e625
added move contacts
akanshaaa19 Aug 8, 2024
7f40de7
fixed csv issue
akanshaaa19 Aug 8, 2024
3c634e2
Merge branch 'master' of github.com:glific/glific-frontend into featu…
akanshaaa19 Aug 8, 2024
9fe5f36
changed cypress branch
akanshaaa19 Aug 8, 2024
7bc6d0f
fixed test cases
akanshaaa19 Aug 8, 2024
51b9eab
updated backend branch
akanshaaa19 Aug 9, 2024
fae3972
changed cypress branch
akanshaaa19 Aug 9, 2024
16106d3
updated backend branch
akanshaaa19 Aug 9, 2024
e6f6164
updated backend branch
akanshaaa19 Aug 9, 2024
4db15a8
fixed move contacts api
akanshaaa19 Aug 9, 2024
5bfdcf3
fixed minor issue
akanshaaa19 Aug 9, 2024
da01ffe
deepscan fixes and test cases
akanshaaa19 Aug 9, 2024
17b0e12
added test cases
akanshaaa19 Aug 9, 2024
08115ef
Merge branch 'master' of github.com:glific/glific-frontend into featu…
akanshaaa19 Aug 12, 2024
a11a5ec
deepscan fixes and test cases
akanshaaa19 Aug 12, 2024
971c393
Merge branch 'master' into feature/bulk-contact
kurund Aug 20, 2024
c30fc1b
import screen cleanup
kurund Aug 20, 2024
0f94d7b
Merge branch 'feature/bulk-contact' of github.com:glific/glific-front…
akanshaaa19 Aug 20, 2024
1fbfa26
Merge branch 'master' of github.com:glific/glific-frontend into featu…
akanshaaa19 Aug 20, 2024
f9a42c4
worked on feedbacks
akanshaaa19 Aug 20, 2024
9e539be
Merge branch 'master' of github.com:glific/glific-frontend into featu…
akanshaaa19 Aug 21, 2024
dd42e28
fixes to cypress tests
kurund Aug 27, 2024
fc6411c
Merge remote-tracking branch 'origin/master' into feature/bulk-contact
kurund Aug 27, 2024
af8733f
update import buttons
kurund Aug 27, 2024
948ffae
design consistency, remove action button icon
kurund Aug 27, 2024
a7491c6
more cleanup
kurund Aug 27, 2024
d8f8bd3
added cancel in dialog
akanshaaa19 Aug 28, 2024
053a0a9
Merge branch 'feature/bulk-contact' of github.com:glific/glific-front…
akanshaaa19 Aug 28, 2024
8b8e885
worked on feedbacks
akanshaaa19 Aug 28, 2024
640c636
fixed deepsca issues
akanshaaa19 Aug 28, 2024
9321060
fixed test cases
akanshaaa19 Aug 28, 2024
d28ae47
added test cases
akanshaaa19 Aug 28, 2024
edad1d2
updated mocks
akanshaaa19 Aug 28, 2024
1a43366
update info svg
kurund Aug 28, 2024
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
3 changes: 2 additions & 1 deletion .github/workflows/cypress-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ jobs:
git clone https://github.com/glific/glific.git
echo done. go to dir.
cd glific
git checkout importContact
echo done. start dev.secret.exs config
cd priv
mkdir cert
Expand Down Expand Up @@ -96,7 +97,7 @@ jobs:
git clone https://github.com/glific/cypress-testing.git
echo done. go to dir.
cd cypress-testing
git checkout main
git checkout feat/contacts-import
cd ..
cp -r cypress-testing/cypress cypress
yarn add cypress@13.6.2
Expand Down
11 changes: 10 additions & 1 deletion src/components/UI/Form/Checkbox/Checkbox.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
.Checkbox {
margin-bottom: -10px;
display: flex;
align-items: center;
flex-direction: column;
}

.Label {
Expand Down Expand Up @@ -33,3 +33,12 @@
.Disabled {
opacity: 60%;
}

.DangerText {
margin-left: 30px;
font-size: 12px;
margin-top: -12px;
line-height: 18px;
font-weight: 400;
color: #fb5c5c;
}
67 changes: 36 additions & 31 deletions src/components/UI/Form/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Checkbox as CheckboxElement, FormControlLabel } from '@mui/material';
import { Checkbox as CheckboxElement, FormControlLabel, FormHelperText } from '@mui/material';
import InfoIcon from 'assets/images/icons/Info.svg?react';
import Tooltip from 'components/UI/Tooltip/Tooltip';
import styles from './Checkbox.module.css';
Expand Down Expand Up @@ -38,37 +38,42 @@ export const Checkbox = ({

return (
<div className={`${styles.Checkbox} ${className} ${disabled && styles.Disabled}`}>
<FormControlLabel
control={
<CheckboxElement
data-testid="checkboxLabel"
classes={darkCheckbox ? { colorPrimary: styles.CheckboxColor } : null}
{...field}
color="primary"
checked={field.value ? field.value : false}
onChange={handleChangeCallback}
disabled={disabled}
/>
}
labelPlacement="end"
label={title}
classes={{
label: addLabelStyle ? styles.Label : undefined,
root: styles.Root,
}}
/>
{info?.title && infoType === 'tooltip' && (
<Tooltip tooltipClass={styles.Tooltip} title={info.title} placement="right">
<InfoIcon className={styles.InfoIcon} />
</Tooltip>
)}
{info && infoType === 'dialog' && (
<InfoIcon
className={styles.InfoIcon}
data-testid="info-icon"
onClick={() => handleInfoClick()}
<div>
<FormControlLabel
control={
<CheckboxElement
data-testid="checkboxLabel"
classes={darkCheckbox ? { colorPrimary: styles.CheckboxColor } : null}
{...field}
color="primary"
checked={field.value ? field.value : false}
onChange={handleChangeCallback}
disabled={disabled}
/>
}
labelPlacement="end"
label={title}
classes={{
label: addLabelStyle ? styles.Label : undefined,
root: styles.Root,
}}
/>
)}
{info?.title && infoType === 'tooltip' && (
<Tooltip tooltipClass={styles.Tooltip} title={info.title} placement="right">
<InfoIcon className={styles.InfoIcon} />
</Tooltip>
)}
{info && infoType === 'dialog' && (
<InfoIcon
className={styles.InfoIcon}
data-testid="info-icon"
onClick={() => handleInfoClick()}
/>
)}
</div>
{form && form.errors[field.name] && form.touched[field.name] ? (
<FormHelperText className={styles.DangerText}>{form.errors[field.name]}</FormHelperText>
) : null}
</div>
);
};
4 changes: 3 additions & 1 deletion src/components/UI/ImportButton/ImportButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ export interface ImportButtonProps {
title: string;
onImport: any;
afterImport: any;
id?: string;
}

export const ImportButton = ({ title, onImport, afterImport }: ImportButtonProps) => {
export const ImportButton = ({ title, onImport, afterImport, id }: ImportButtonProps) => {
const inputRef = useRef<HTMLInputElement>(null);
const changeHandler = (event: any) => {
const media = event.target.files[0];
Expand All @@ -29,6 +30,7 @@ export const ImportButton = ({ title, onImport, afterImport }: ImportButtonProps
name="file"
onChange={changeHandler}
data-testid="import"
id={id}
/>
<Button
onClick={() => {
Expand Down
20 changes: 16 additions & 4 deletions src/containers/Collection/CollectionList/CollectionList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,28 @@ import {
updateCollectionWaGroupQuery,
} from 'mocks/Groups';
import { setNotification } from 'common/notification';
import { setVariables } from 'common/constants';
import { CONTACTS_COLLECTION, setVariables } from 'common/constants';
import { setUserRolePermissions } from 'context/role';

const variables = {
filter: {
groupType: CONTACTS_COLLECTION,
},
opts: {
limit: 50,
offset: 0,
order: 'ASC',
orderWith: 'label',
},
};

const mocks = [
countCollectionQuery,
countCollectionQuery,
countCollectionQuery,
filterCollectionQuery,
filterCollectionQuery,
filterCollectionQuery,
filterCollectionQuery(variables),
filterCollectionQuery(variables),
filterCollectionQuery(variables),
getPublishedFlowQuery,
getPublishedFlowQuery,
getCollectionContactsQuery,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
.Container {
padding-left: 40px;
margin-top: 36px;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 50%;
max-height: 65%;
background-color: #fff;
border-radius: 15px;
padding: 1rem 2rem;
}

.Instructions {
max-width: 500px;
color: #93a29b;
font-size: 16px;
}

Expand Down Expand Up @@ -105,3 +110,8 @@
position: absolute;
right: 12px;
}

.Buttons button {
border-radius: 8px;
width: 30%;
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useMutation } from '@apollo/client';

import { CONTACT_MANAGE_HELP_LINK, UPLOAD_CONTACTS_ADMIN_SAMPLE } from 'config';
import { Button } from 'components/UI/Form/Button/Button';
import { Heading } from 'components/UI/Heading/Heading';
import UploadIcon from 'assets/images/icons/UploadLight.svg?react';
import FileIcon from 'assets/images/icons/Document/Light.svg?react';
import CrossIcon from 'assets/images/icons/Cross.svg?react';
import { MOVE_CONTACTS } from 'graphql/mutations/Contact';
import { exportCsvFile, slicedString } from 'common/utils';
import { slicedString } from 'common/utils';
import { setNotification } from 'common/notification';
import styles from './AdminContactManagement.module.css';
import { contactVariablesInfo } from 'common/HelpData';

export const AdminContactManagement = () => {
const [fileName, setFileName] = useState<string>('');
const [errors, setErrors] = useState<any>([]);
const [csvContent, setCsvContent] = useState<String | null | ArrayBuffer>('');
const [uploadingContacts, setUploadingContacts] = useState(false);
const { t } = useTranslation();

const [moveContacts] = useMutation(MOVE_CONTACTS, {
onCompleted: (data: any) => {
if (data.errors) {
setErrors(data.errors);
onCompleted: ({ moveContacts }) => {
const { errors, status } = moveContacts;
if (errors) {
setErrors(errors);

Check warning on line 23 in src/containers/ContactManagement/AdminContactManagement/AdminContactManagement.tsx

View check run for this annotation

Codecov / codecov/patch

src/containers/ContactManagement/AdminContactManagement/AdminContactManagement.tsx#L23

Added line #L23 was not covered by tests
} else {
exportCsvFile(data.moveContacts.csvRows, 'results');
setUploadingContacts(false);
setNotification(t('Contacts have been updated'));
setNotification(status);
}
setFileName('');
},
Expand Down Expand Up @@ -58,13 +53,10 @@
};

return (
<div>
<Heading
formTitle="Contact Management"
showHeaderHelp={false}
helpData={contactVariablesInfo}
/>
<div className={styles.Container}>
<div className={styles.Container}>
<div>
<h2>Move contacts</h2>

<div className={styles.Instructions}>
You can move contacts to collections in bulk or update their contact information. Please
create csv file that exactly matches the sample. Here are the &nbsp;
Expand All @@ -85,6 +77,7 @@
<>
<span>{fileName}</span>
<CrossIcon
data-testid="cross-icon"
className={styles.CrossIcon}
onClick={(event: any) => {
event.preventDefault();
Expand Down Expand Up @@ -121,6 +114,9 @@
</div>
))}
</div>
</div>

<div className={styles.Buttons}>
<Button
data-testid="uploadButton"
variant="contained"
Expand Down
30 changes: 30 additions & 0 deletions src/containers/ContactManagement/ContactManagement.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.MainContainer {
display: flex;
column-gap: 1rem;
width: 100% !important;
height: 100vh !important;
background-color: #f8faf5;
padding: 1rem;
color: #000;
}

.MainContainer h2 {
margin-top: 0;
margin-bottom: 1rem;
}

.Container {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 50%;
max-height: 65%;
background-color: #fff;
border-radius: 15px;
padding: 1.5rem 2rem;
}

.Buttons button {
border-radius: 8px;
width: 30%;
}
34 changes: 26 additions & 8 deletions src/containers/ContactManagement/ContactManagement.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { render, screen } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';

import { BrowserRouter as Router } from 'react-router-dom';

import { getAllOrganizations } from 'mocks/Organization';
import { setUserSession } from 'services/AuthService';
import ContactManagement from './ContactManagement';
import { filterCollectionQuery } from 'mocks/Collection';
import { CONTACTS_COLLECTION } from 'common/constants';

const mocks = getAllOrganizations;
const mocks = [
filterCollectionQuery({
filter: {
groupType: CONTACTS_COLLECTION,
},
opts: {
limit: 50,
offset: 0,
order: 'ASC',
},
}),
];

const contactManagement = (
<MockedProvider mocks={mocks} addTypename={false}>
Expand All @@ -17,9 +28,16 @@ const contactManagement = (
</MockedProvider>
);

setUserSession(JSON.stringify({ roles: [{ label: 'Staff' }], organization: { id: '1' } }));

test('Show unauthorized access for staff user', async () => {
test('it opens contact upload dialog', async () => {
render(contactManagement);
expect(screen.getByText('Unauthorized access')).toBeInTheDocument();

await waitFor(() => {
expect(screen.getByText('Contact Management')).toBeInTheDocument();
});

fireEvent.click(screen.getByTestId('uploadContactsBtn'));

await waitFor(() => {
expect(screen.getByText('Upload Contacts')).toBeInTheDocument();
});
});
Loading
Loading