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: send individuals emails with pluggable component #6

Conversation

johnvente
Copy link

@johnvente johnvente commented Dec 18, 2023

Description

This feature will allow sending emails to expected emails of students in the course using pluggable component made here

NOTE: For scheduled emails to be sent, we would need to modify this endpoint /api/instructor_task/v1/schedules/course-v1:edX+DemoX+Demo_Course/bulk_email/?page=1 to include "extra_targets" in order to view the previously added emails.

DEMO

pluggable-communications

Pluggin loaded

plugin-loaded

How to test it

If you are using devstack

  1. Go to workspace and clone this branch
cd ~/workspace && git remote add fork [email protected]:eduNEXT/frontend-app-communications.git
git fetch fork jv/feat-send-individual-email-learners && git checkout jv/feat-send-individual-email-learners
  1. Go to the mfe repository, use node version in the repo and install dependencies
cd ~/workspace/frontend-app-communications && nvm use && npm install

  1. inside frontend-app-communications run
npm run start
  1. Go to http://localhost:1984/courses/course-v1:edX+DemoX+Demo_Course/bulk_email Or
    http://localhost:1984/courses/{{id_course}}/bulk_email

  2. In the input with this label "Add individual learner" search an student with email/name/username and click on the user that you wish

  3. Fill out the fields Subject and Body

@codecov-commenter
Copy link

codecov-commenter commented Dec 18, 2023

Codecov Report

Attention: 11 lines in your changes are missing coverage. Please review.

Comparison is base (cd64f47) 83.42% compared to head (ced6b97) 81.65%.

Files Patch % Lines
.../bulk-email-tool/bulk-email-form/BulkEmailForm.jsx 57.14% 9 Missing ⚠️
...l-form/bulk-email-recipient/BulkEmailRecipient.jsx 33.33% 2 Missing ⚠️
Additional details and impacted files
@@                       Coverage Diff                       @@
##           jv/pluggable-component-slot       #6      +/-   ##
===============================================================
- Coverage                        83.42%   81.65%   -1.77%     
===============================================================
  Files                               48       48              
  Lines                              718      747      +29     
  Branches                           140      144       +4     
===============================================================
+ Hits                               599      610      +11     
- Misses                             119      137      +18     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@johnvente johnvente requested a review from a team December 18, 2023 14:19
Copy link
Member

@mariajgrimaldi mariajgrimaldi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main question is about the changes in the MFE not related to the component slots, do we need them here (right in the MFE) so the plugin works? or can they be moved to the plugin?

import { logError } from '@edx/frontend-platform/logging';

export async function getLearnersEmailInstructorTask(courseId, search) {
const endpointUrl = `${getConfig().LMS_BASE_URL}/platform-plugin-communications/${courseId}/api/search_learners?query=${search}&page=1&page_size=10`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the page and page_size fixed? shouldn't it be parametrized?

Comment on lines +30 to +31
// eslint-disable-next-line no-console
console.error('error autocomplete input', error.message);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why a console error instead of a standard logError?

Comment on lines +69 to +70
renderMenuItemChildren={({ name, email }) => (
<span data-testid="autocomplete-email-option">{name ? `${name} -` : name} {email}</span>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The search query can also be the username. Would the name/email combination appear even though I'm looking for the student by their username? wouldn't that be confusing?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add the username as well, no problem. For me is not confusing due to the user can see the name/email of the student in the list an selected that one

Comment on lines +73 to +75
const emailsIndividualLearners = emailLearnersList.map(({ email }) => email);
const extraTargets = { emails: emailsIndividualLearners };
const emailRecipients = editor.emailRecipients.filter((recipient) => recipient !== 'individual-learners-emails');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how would we do this from the plugin? since the idea is not to modify the MFE

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case that won't be an option due to we would have to rewrite BulkEmailForm.js becuase all the logic is here and I don't think so that we have enough time for that

Comment on lines +220 to +248
/*
This will be checking if there are emails added to the emailLearnersList state
if so, we will delete emailRecipients "learners" because that is for all learners
if not, we will delete the individual-learners-emails from emailRecipients because of we won't use the emails
*/
useEffect(() => {
if (emailLearnersList.length && !editor.emailRecipients.includes('individual-learners-emails')) {
dispatch(addRecipient('individual-learners-emails'));
if (editor.emailRecipients.includes('learners')) {
dispatch(removeRecipient('learners'));
}
} else if (!emailLearnersList.length && editor.emailRecipients.includes('individual-learners-emails')) {
dispatch(removeRecipient('individual-learners-emails'));
}
}, [dispatch, editor.emailRecipients, emailLearnersList]);

// When the user selects an email from input autocomplete list
const handleEmailLearnersSelected = (emailSelected) => {
const [firstItem] = emailSelected;
if (firstItem) {
setEmailLearnersList([...emailLearnersList, firstItem]);
}
};

// To delete an email from learners list, that list is on the bottom of the input autocomplete
const handleDeleteEmailLearnerSelected = (idToDelete) => {
const setEmailLearnersListUpdated = emailLearnersList.filter(({ id }) => id !== idToDelete);
setEmailLearnersList(setEmailLearnersListUpdated);
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here about not modifying the MFE since that means more maintenance efforts

@johnvente
Copy link
Author

johnvente commented Dec 18, 2023

My main question is about the changes in the MFE not related to the component slots, do we need them here (right in the MFE) so the plugin works? or can they be moved to the plugin?

In this particular case, we need to write changes in the MFE due to the form has a React context that is and Redux shared throw it's component so I need to change in that part. If we don't want to rewrite the mfe anymore we should wrap the all form with the pluggable component and make the form again and that doesn't make sense. So in this particular case we should modify that part of the code

@BryanttV
Copy link

Hi @johnvente, I tested the functionality and it works correctly. I would like to comment on two things:

  1. To search a user you need to include 3 characters minimum. Is that how it should work?
  2. I think the recipients container should only be displayed once the first user is added 🤔

@johnvente
Copy link
Author

Hi @johnvente, I tested the functionality and it works correctly. I would like to comment on two things:

  1. To search a user you need to include 3 characters minimum. Is that how it should work?
  2. I think the recipients container should only be displayed once the first user is added 🤔

Hi @BryanttV

  1. Yep, is recommended to have 3 characters minimum should work like that
  2. I can hide the container while it doesn't have emails added

@johnvente
Copy link
Author

I will close this pull request and create another one with 100% plugins changes
cc: @BryanttV

@johnvente johnvente closed this Dec 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants