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

feat: Add Infinite scroll to all tag screens & refactor code for better readability (GSoC) #2387

Merged
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
66e1af2
add people to tag functaionality
meetulr Oct 25, 2024
edb8360
minor change
meetulr Oct 25, 2024
689ad90
more translations
meetulr Oct 25, 2024
abaf86e
minor change
meetulr Oct 26, 2024
7b7b6bf
add a variable for page size
meetulr Oct 26, 2024
72b6fd3
add tag actions
meetulr Oct 26, 2024
3b97043
add tests
meetulr Oct 26, 2024
6c13484
translations
meetulr Oct 26, 2024
76f5fbe
change to infinite scroll
meetulr Oct 27, 2024
d022c8d
add subtags infinite scroll
meetulr Oct 27, 2024
27227a9
Merge branch 'tagActions' into changeToInfiniteScroll
meetulr Oct 27, 2024
d11a6ee
extract common variables to utils
meetulr Oct 27, 2024
01b4b65
minor correction
meetulr Oct 27, 2024
c882dd6
Merge branch 'tagActions' into changeToInfiniteScroll
meetulr Oct 27, 2024
ba59202
more design adjustments
meetulr Oct 27, 2024
a59da70
add tests
meetulr Oct 27, 2024
f773005
add scrollbar for infinite scroll
meetulr Oct 27, 2024
e42b8fe
extract infinite scroll loader
meetulr Oct 27, 2024
ab3310a
minor adjustment
meetulr Oct 27, 2024
b223e21
refactoring
meetulr Oct 27, 2024
1b4b913
Merge branch 'develop' of https://github.com/PalisadoesFoundation/tal…
meetulr Oct 27, 2024
a8bca91
exclude ManageTag from countline check
meetulr Oct 27, 2024
58af286
fix linting
meetulr Oct 27, 2024
59f5e03
fix linting
meetulr Oct 27, 2024
879ef42
fix linting
meetulr Oct 27, 2024
6a79d51
make coderabbit suggested changes
meetulr Oct 28, 2024
9bc25d7
more changes
meetulr Oct 28, 2024
926f766
more changes
meetulr Oct 28, 2024
d3e91ac
minor correction
meetulr Oct 28, 2024
2a49ea0
add error component for tagNode subtags query
meetulr Oct 28, 2024
052aead
fix translation
meetulr Oct 28, 2024
d8d657a
fix translation
meetulr Oct 28, 2024
e9a86f8
Merge branch 'tagActions' into refactoringAndDesignAdjustments
meetulr Oct 28, 2024
4ae2507
remove unused css classes
meetulr Oct 28, 2024
ffbdffc
refactor ManageTag file to reduce its size
meetulr Oct 30, 2024
f4c7814
update pull-request check
meetulr Oct 30, 2024
95a1138
minor adjustments
meetulr Oct 30, 2024
4efe79e
minor correction
meetulr Oct 30, 2024
bbab01c
Merge branch 'develop' of https://github.com/PalisadoesFoundation/tal…
meetulr Oct 30, 2024
6f65f9f
minor change
meetulr Oct 30, 2024
eb5b7ea
correction
meetulr Oct 30, 2024
ee1cf2d
minor changes
meetulr Oct 30, 2024
5ac6cbe
minor change
meetulr Oct 30, 2024
9626c68
coderabbitai changes
meetulr Oct 30, 2024
9be6fa8
more changes
meetulr Oct 30, 2024
63febd0
fix dataGrid classes
meetulr Oct 30, 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
Prev Previous commit
Next Next commit
make coderabbit suggested changes
meetulr committed Oct 28, 2024
commit 6a79d5133c990ac8b2914fb4f27f95c0ccb3fe92
3 changes: 2 additions & 1 deletion public/locales/en/translation.json
Original file line number Diff line number Diff line change
@@ -352,7 +352,8 @@
"tagName": "Name",
"tagUpdationSuccess": "Tag updated successfully",
"tagRemovalSuccess": "Tag deleted successfully",
"noTagSelected": "No Tag Selected"
"noTagSelected": "No Tag Selected",
"changeNameToEdit": "Change the name to make an update"
},
"userListCard": {
"addAdmin": "Add Admin",
3 changes: 2 additions & 1 deletion public/locales/fr/translation.json
Original file line number Diff line number Diff line change
@@ -352,7 +352,8 @@
"tagName": "Nom",
"tagUpdationSuccess": "Étiquette mise à jour avec succès",
"tagRemovalSuccess": "Étiquette supprimée avec succès",
"noTagSelected": "Aucun tag sélectionné"
"noTagSelected": "Aucun tag sélectionné",
"changeNameToEdit": "Modifiez le nom pour faire une mise à jour"
},
"userListCard": {
"addAdmin": "Ajouter un administrateur",
3 changes: 2 additions & 1 deletion public/locales/hi/translation.json
Original file line number Diff line number Diff line change
@@ -352,7 +352,8 @@
"tagName": "नाम",
"tagUpdationSuccess": "टैग सफलतापूर्वक अपडेट की गई",
"tagRemovalSuccess": "टैग सफलतापूर्वक हटाई गई",
"noTagSelected": "कोई टैग चयनित नहीं"
"noTagSelected": "कोई टैग चयनित नहीं",
"changeNameToEdit": "अपडेट करने के लिए नाम बदलें"
},
"userListCard": {
"addAdmin": "व्यवस्थापक जोड़ें",
3 changes: 2 additions & 1 deletion public/locales/sp/translation.json
Original file line number Diff line number Diff line change
@@ -352,7 +352,8 @@
"tagName": "Nombre",
"tagUpdationSuccess": "Etiqueta actualizada con éxito",
"tagRemovalSuccess": "Etiqueta eliminada con éxito",
"noTagSelected": "Ninguna etiqueta seleccionada"
"noTagSelected": "Ninguna etiqueta seleccionada",
"changeNameToEdit": "Cambia el nombre para hacer una actualización"
},
"userListCard": {
"joined": "Unido",
3 changes: 2 additions & 1 deletion public/locales/zh/translation.json
Original file line number Diff line number Diff line change
@@ -352,7 +352,8 @@
"tagName": "名称",
"tagUpdationSuccess": "标签更新成功",
"tagRemovalSuccess": "标签删除成功",
"noTagSelected": "未选择标签"
"noTagSelected": "未选择标签",
"changeNameToEdit": "更改名称以进行更新"
},
"userListCard": {
"addAdmin": "添加管理员",
10 changes: 6 additions & 4 deletions src/components/TagActions/TagActions.test.tsx
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ import {
fireEvent,
cleanup,
waitFor,
act,
} from '@testing-library/react';
import { Provider } from 'react-redux';
import { MemoryRouter, Route, Routes } from 'react-router-dom';
@@ -26,10 +27,11 @@ import { MOCKS, MOCKS_ERROR } from './TagActionsMocks';
const link = new StaticMockLink(MOCKS, true);
const link2 = new StaticMockLink(MOCKS_ERROR, true);

async function wait(): Promise<void> {
await waitFor(() => {
// The waitFor utility automatically uses optimal timing
return Promise.resolve();
async function wait(ms = 500): Promise<void> {
await act(() => {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
});
}

59 changes: 20 additions & 39 deletions src/components/TagActions/TagActions.tsx
Original file line number Diff line number Diff line change
@@ -82,7 +82,7 @@ const TagActions: React.FC<InterfaceTagActionsProps> = ({
skip: !assignToTagsModalIsOpen,
});

const userTagsList = orgUserTagsData?.organizations[0].userTags.edges.map(
const userTagsList = orgUserTagsData?.organizations[0]?.userTags.edges.map(
(edge) => edge.node,
);

@@ -246,49 +246,32 @@ const TagActions: React.FC<InterfaceTagActionsProps> = ({
};

const [assignToTags] = useMutation(ASSIGN_TO_TAGS);

const assignToSelectedTags = async (
e: FormEvent<HTMLFormElement>,
): Promise<void> => {
e.preventDefault();

try {
const { data } = await assignToTags({
variables: {
currentTagId,
selectedTagIds: selectedTags.map((selectedTag) => selectedTag._id),
},
});

if (data) {
toast.success(t('successfullyAssignedToTags'));
hideAssignToTagsModal();
}
} catch (error: unknown) {
/* istanbul ignore next */
if (error instanceof Error) {
toast.error(error.message);
}
}
};

const [removeFromTags] = useMutation(REMOVE_FROM_TAGS);

const removeFromSelectedTags = async (
const handleTagAction = async (
e: FormEvent<HTMLFormElement>,
): Promise<void> => {
e.preventDefault();

const mutationObject = {
variables: {
currentTagId,
selectedTagIds: selectedTags.map((selectedTag) => selectedTag._id),
},
};

try {
const { data } = await removeFromTags({
variables: {
currentTagId,
selectedTagIds: selectedTags.map((selectedTag) => selectedTag._id),
},
});
const { data } =
tagActionType === 'assignToTags'
? await assignToTags(mutationObject)
: await removeFromTags(mutationObject);

if (data) {
toast.success(t('successfullyRemovedFromTags'));
if (tagActionType === 'assignToTags') {
toast.success(t('successfullyAssignedToTags'));
} else {
toast.success(t('successfullyRemovedFromTags'));
}
hideAssignToTagsModal();
}
} catch (error: unknown) {
@@ -306,8 +289,6 @@ const TagActions: React.FC<InterfaceTagActionsProps> = ({
<WarningAmberRounded className={styles.errorIcon} fontSize="large" />
<h6 className="fw-bold text-danger text-center">
{t('errorOccurredWhileLoadingOrganizationUserTags')}
<br />
{orgUserTagsError.message}
</h6>
</div>
</div>
@@ -337,8 +318,8 @@ const TagActions: React.FC<InterfaceTagActionsProps> = ({
<Form
onSubmitCapture={(e) =>
tagActionType === 'assignToTags'
? assignToSelectedTags(e)
: removeFromSelectedTags(e)
? handleTagAction(e)
: handleTagAction(e)
}
>
<Modal.Body className="pb-0">
15 changes: 6 additions & 9 deletions src/components/TagActions/TagActionsMocks.ts
Original file line number Diff line number Diff line change
@@ -366,8 +366,8 @@ export const MOCKS = [
},
],
pageInfo: {
startCursor: '1',
endCursor: '10',
startCursor: 'subTag1',
endCursor: 'subTag10',
hasNextPage: true,
hasPreviousPage: false,
},
@@ -382,7 +382,7 @@ export const MOCKS = [
query: USER_TAG_SUB_TAGS,
variables: {
id: '1',
after: '10',
after: 'subTag10',
first: TAGS_QUERY_LIMIT,
},
},
@@ -407,8 +407,8 @@ export const MOCKS = [
},
],
pageInfo: {
startCursor: '11',
endCursor: '11',
startCursor: 'subTag11',
endCursor: 'subTag11',
hasNextPage: false,
hasPreviousPage: true,
},
@@ -458,10 +458,7 @@ export const MOCKS_ERROR = [
query: ORGANIZATION_USER_TAGS_LIST,
variables: {
id: '123',
after: null,
before: null,
first: 5,
last: null,
first: TAGS_QUERY_LIMIT,
},
},
error: new Error('Mock Graphql Error'),
7 changes: 7 additions & 0 deletions src/screens/ManageTag/ManageTag.test.tsx
Original file line number Diff line number Diff line change
@@ -49,6 +49,7 @@ async function wait(ms = 500): Promise<void> {
jest.mock('react-toastify', () => ({
toast: {
success: jest.fn(),
info: jest.fn(),
error: jest.fn(),
},
}));
@@ -394,6 +395,12 @@ describe('Manage Tag Page', () => {
});
userEvent.click(screen.getByTestId('editTag'));

userEvent.click(screen.getByTestId('editTagSubmitBtn'));

await waitFor(() => {
expect(toast.info).toHaveBeenCalledWith(translations.changeNameToEdit);
});

const tagNameInput = screen.getByTestId('tagNameInput');
await userEvent.clear(tagNameInput);
await userEvent.type(tagNameInput, 'tag 1 edited');
18 changes: 12 additions & 6 deletions src/screens/ManageTag/ManageTag.tsx
Original file line number Diff line number Diff line change
@@ -87,6 +87,10 @@ function ManageTag(): JSX.Element {
setAssignToTagsModalIsOpen(false);
};

const showEditTagModal = (): void => {
setEditTagModalIsOpen(true);
};

const hideEditTagModal = (): void => {
setEditTagModalIsOpen(false);
};
@@ -159,6 +163,7 @@ function ManageTag(): JSX.Element {
const [edit] = useMutation(UPDATE_USER_TAG);

const [newTagName, setNewTagName] = useState<string>('');
const currentTagName = userTagAssignedMembersData?.getUserTag.name ?? '';

useEffect(() => {
setNewTagName(userTagAssignedMembersData?.getUserTag.name ?? '');
@@ -167,6 +172,11 @@ function ManageTag(): JSX.Element {
const editTag = async (e: FormEvent<HTMLFormElement>): Promise<void> => {
e.preventDefault();

if (newTagName === currentTagName) {
toast.info(t('changeNameToEdit'));
return;
}

try {
const { data } = await edit({
variables: {
@@ -524,18 +534,14 @@ function ManageTag(): JSX.Element {
<hr className="mb-1 mt-2" />

<div
onClick={() => {
setEditTagModalIsOpen(true);
}}
onClick={showEditTagModal}
className="ms-5 mt-3 mb-2 btn btn-primary btn-sm w-75"
data-testid="editTag"
>
{tCommon('edit')}
</div>
<div
onClick={() => {
setRemoveTagModalIsOpen(true);
}}
onClick={toggleRemoveUserTagModal}
className="ms-5 mb-2 btn btn-danger btn-sm w-75"
data-testid="removeTag"
>