-
Notifications
You must be signed in to change notification settings - Fork 4
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 trial days remaining banner #72
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great so far! Just a couple suggestions. Also this may be an unrelated bug (in which case we could create a separate ticket), but I noticed that, in the demo, the "bubble" that contains the message seems to be missing for the response message. Is that just the way you're testing/mocking out the xpert chatgpt prompt logic?
src/data/thunks.js
Outdated
@@ -70,6 +70,9 @@ export function getChatResponse(courseId, unitId, promptExperimentVariationKey = | |||
|
|||
dispatch(setApiIsLoading(false)); | |||
dispatch(addChatMessage(message.role, message.content, courseId, promptExperimentVariationKey)); | |||
if (message.audit_trial_created) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is audit_trial_created
coming from? Are you planning to add it to the backend API? Do we have a ticket for that? If so, make a note of that here, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make sense to sync up with Marcos to see how he plans to incorporate getChatResponse
into this work, since his work may affect how this function is called.
As an alternative to message.audit_trial_created
, it may also make sense to pass a variable to this thunk (e.g. rehydrateChatSummary
) so that the frontend can control when to re-fetch this data. For example, we may know when a learner is posting a message from the audit trial CTA, depending on Marcos's approach. This approach would allow us to avoid also needing to change the backend API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I was experimenting with sending a new value from the backend, and forgot to put this back to its original state. I'm going to change this such that the chat-summary endpoint is called every time a message is sent so that this works while I decide on a more efficient solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To follow up on this, I added this code to the backend only on my local setup to make this work:
response = self._get_next_message(request, courserun_key, course_run_id)
# Temp for testing
audit_trial_created = True
if audit_trial_created:
# TODO: Determine if this is something we should send to gate the extra calls to chat summary
response.data['audit_trial_created'] = True
return response
I'll leave this as is for now until we're all on the same page on how/when to rehydrate the chat summary related state variables in the frontend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, reverting back to not having a audit_trial_created
value in the frontend or backend to keep things simple as agreed upon. We will just call chat-summary with every message received. We can add this feature later if we have performance issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: Ignore my replies above to this thread, this is what I'm doing for now:
Per our Slack discussion, I decided on an approach where we will only refresh the chat-summary after the first message is sent. This isn't "optimal", but it at least prevents us from calling the chat-summary endpoint w/ every message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Demo video for that feature:
Screen.Recording.2024-12-12.at.1.10.24.PM.mov
src/components/Sidebar/index.jsx
Outdated
const oneDay = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds | ||
const daysRemaining = Math.ceil((auditTrialExpirationDate - Date.now()) / oneDay); | ||
|
||
if (daysRemaining > 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although I'm not familiar with it, we should consider Marcos's suggestion of Intl.RelativeTimeFormat to better internationalize these strings. Although, we don't internationalize this feature anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried this out, seems like using this means we'd have to change the banner text for this as, at least in English, the RelativeTimeFormat spits out "in X days", with no way to change the exact wording. Wondering if that's worth doing given that we aren't intl'ing right now.
src/components/Sidebar/index.jsx
Outdated
// Get this to work | ||
const getDaysRemainingMessage = () => { | ||
// if enrollment mode is NOT upgrade eligible, there's no audit trial data | ||
if (!isUpgradeEligible) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started a thread in Slack, but I don't think isUpgradeEligible
is computed the same way on the backend, which will lead to issues. I don't think that's an issue for your code changes, but I wanted to flag that. We can chat in Slack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: This is being addressed in https://2u-internal.atlassian.net/browse/COSMO-612
Demo of the now-operational upgrade URL: Screen.Recording.2024-12-12.at.11.59.12.AM.mov |
bf41221
to
27d4b79
Compare
22dfc95
to
d366bc0
Compare
Demo of how this looks after rebasing onto Marcos' PR with the Disclosure: #73 (review) Screen.Recording.2024-12-16.at.3.12.06.PM.mov |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't have time to review this today, but I wanted to leave this comment. If the PR still needs a review tomorrow, I'll take a look then.
src/data/thunks.js
Outdated
@@ -68,6 +110,12 @@ export function getChatResponse(courseId, unitId, promptExperimentVariationKey = | |||
const customQueryParams = promptExperimentVariationKey ? { responseVariation: promptExperimentVariationKey } : {}; | |||
const message = await fetchChatResponse(courseId, messageList, unitId, customQueryParams); | |||
|
|||
// Refresh chat summary only on the first message so we can tell if the user has initiated an audit trial | |||
// NOTE: This is a bit of a hacky solution that may be refined later | |||
if (messageList.length === 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is fine to have as a POC, but I don't think we should merge this. This is going to make an API call for everyone after they send their first message, which is a lot of extraneous API calls. At a minimum, we should only make this call when the learner is eligible for an audit trial.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted, added a condition to only show this to upgrade eligible learners as well.
045ba42
to
27104c2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nits, but otherwise this looks good!
@@ -3,7 +3,7 @@ import { getOptimizely } from '../data/optimizely'; | |||
const trackChatBotMessageOptimizely = (userId, userAttributes = {}) => { | |||
const optimizelyInstance = getOptimizely(); | |||
|
|||
if (!optimizelyInstance) { return; } | |||
if (!optimizelyInstance || Object.keys(optimizelyInstance).length === 0) { return; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this line causing issues?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line was causing issues on my local setup, not sure if it was due to something missing on my end. I can put this back if that's preferred.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you probably need to add { moduleName: '@optimizely/react-sdk', dir: '../src/frontend-plugin-advertisements/src/mocks/optimizely', dist: '.' },
to your frontend-app-learning module.config.js
file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That line is in my config file so I'm not sure what's up there...
module.exports = {
/*
Modules you want to use from local source code. Adding a module here means that when this app
runs its build, it'll resolve the source from peer directories of this app.
moduleName: the name you use to import code from the module.
dir: The relative path to the module's source code.
dist: The sub-directory of the source code where it puts its build artifact. Often "dist".
*/
localModules: [
{ moduleName: '@edx/frontend-lib-special-exams', dir: '../src/frontend-lib-special-exams', dist: 'src' },
{ moduleName: '@edx/frontend-plugin-advertisements', dir: '../src/frontend-plugin-advertisements', dist: 'src' },
{ moduleName: '@optimizely/react-sdk', dir: '../src/frontend-plugin-advertisements/src/mocks/optimizely', dist: '.' },
{ moduleName: '@edx/frontend-lib-learning-assistant', dir: '../src/frontend-lib-learning-assistant', dist: 'src' },
],
};
When I debugged this I found that the optomizelyInstance had a value of {}
so that's why I inserted this condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the issue you're running into? I was not running into issues locally with optimizely so just trying to help narrow down what could be going wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just reviewed the sidebar, but let me know if other areas need review! Happy to take another look. Just had a few questions/nits so far, but looking good!
27104c2
to
d0a8ae5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but please before merging check my nit comment on the tracking for the upgrade link and remove the "Your trial has expired" message since that would never be shown, it will render the paywall instead. (as suggested by Alison and Varsha)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! I think there are a couple of outstanding comments to be addressed but otherwise looks great.
- temp commit as I set up the code
- getting a strange error where hooks aren't being picked up...
e7b9f01
to
1ac0c54
Compare
5547942
to
0352c85
Compare
https://2u-internal.atlassian.net/browse/COSMO-572
Video Demo, showing varying days remaining (fyi the admin page for audit trials is something I did locally, would need to make a PR for it):
Screen.Recording.2024-12-10.at.4.23.55.PM.2.mov