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

Enhance Get Help feature with interactive feedback and improved UI/UX #7635

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

phungmanhcuong
Copy link
Contributor

@phungmanhcuong phungmanhcuong commented Nov 12, 2024

Description:

This pull request introduces enhancements to the Get Help feature, focusing on improved interactivity, usability, and accessibility. Key updates include:

Interactive Feedback Options: Allows users to provide real-time feedback through like, dislike, and dismiss actions on specific feedback items, enhancing engagement and interaction.

UI Improvements: Refined layout and styling to present feedback in an organized, accessible manner.
These improvements aim to create a more responsive, intuitive interface, making it easier for users to navigate and utilize the Get Help feature effectively.

Context:

This aligns with the goals outlined in the Get Help Improvement proposal and supports enhanced student support and accessibility during assessments.

@phungmanhcuong phungmanhcuong marked this pull request as draft November 12, 2024 05:02
@phungmanhcuong phungmanhcuong force-pushed the mcphung/get-help-enhancement branch 5 times, most recently from bacf5a6 to fee8f78 Compare November 14, 2024 16:45
question.id
]?.feedbackFiles ?? [],
);
// TODO: consider removing feedbackFiles
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cysjonathan should I remove this one since its outdated now ?

Copy link
Contributor

Choose a reason for hiding this comment

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

remove which? feedbackFiles or the comment in line 352?
If a variable is not used in this file then yes you can remove it.

Just make sure your code handles feedback across multiple files.

@phungmanhcuong phungmanhcuong marked this pull request as ready for review November 14, 2024 23:37
Copy link
Contributor

@cysjonathan cysjonathan left a comment

Choose a reason for hiding this comment

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

  1. to align with rest of site: don't bold the [Get Help] window title, use normal font-weight
  2. [Get Help] is broken when there are multiple questions (single page). window doesn't appear at the 2nd question.
  3. What happened to "click-on-comment" to focus on the line in code-editor? Will we be dropping that previously implemented feature?
  4. Why are first 2 prompts still "I am stuck" and "My code doesn't work"?
  5. suggestions array should use translations to support internationalization.
  6. Does your code handle feedback across multiple files? I see that you're flattening it.
  7. When the case of no-feedback-generated occurs, the spinner just keeps spinning. Can you handle this properly?
  8. Send button should be disabled until some actual text is in the input.
  9. Positioning should be relative to the [Get Help] button. position seems different in the Single-page layout vs Tabbed layout.
  10. Where's the part of the code where we will handle the updated responses from Codaveri?

const liveFeedback = useAppSelector((state) =>
getFeedbackByQuestionId(state, questionId),
);
const isShowingPopup = !!liveFeedback?.isShowingPopup;
Copy link
Contributor

Choose a reason for hiding this comment

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

Typically convention is to use isXxxOpen, e.g. isDialogOpen, isEditOpen.

</Box>
<Box className="get-help-page-box-full-width">
<TextField
className="get-help-page-textfield"
Copy link
Contributor

Choose a reason for hiding this comment

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

Unless there's a good justification, please use our existing styling (e.g. take the same one from the Programming qns generator) instead of creating new styles.

Copy link
Contributor Author

@phungmanhcuong phungmanhcuong Nov 17, 2024

Choose a reason for hiding this comment

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

I have converted to use the TextField in common lib. In Programming qns generator, they are using the TableCell, a bit different then this case.

}
updateFeedbackForQuestion(draft, questionId, {
isShowingPopup,
suggestedReplies: ['I am stuck', "My code doesn't work"],
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't repeat the first two elements in the suggestions array, you should be only hardcoding strings like this once.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, they are only showed when first time popup open. Then after that, they are randomly generated.

Copy link
Contributor

@cysjonathan cysjonathan left a comment

Choose a reason for hiding this comment

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

Your 2nd, 3rd, 4th, 5th commits seem to all be part of the 1st commit.
e.g. commit 2 removes a depedency in your useEffect array introduced in commit 1,
commit 3 adds newline,
commit 4 adjusts whitespace-formatting only,
commit 5 fixes CSS values introduced in commit 1

Any reason why you separated them?

@phungmanhcuong phungmanhcuong force-pushed the mcphung/get-help-enhancement branch 2 times, most recently from 8e3c5d5 to 20fc4fc Compare November 15, 2024 02:40
@phungmanhcuong phungmanhcuong force-pushed the mcphung/get-help-enhancement branch 5 times, most recently from bf3b349 to 7898ff8 Compare November 17, 2024 13:35
@phungmanhcuong
Copy link
Contributor Author

  1. to align with rest of site: don't bold the [Get Help] window title, use normal font-weight
  2. [Get Help] is broken when there are multiple questions (single page). window doesn't appear at the 2nd question.
  3. What happened to "click-on-comment" to focus on the line in code-editor? Will we be dropping that previously implemented feature?
  4. Why are first 2 prompts still "I am stuck" and "My code doesn't work"?
  5. suggestions array should use translations to support internationalization.
  6. Does your code handle feedback across multiple files? I see that you're flattening it.
  7. When the case of no-feedback-generated occurs, the spinner just keeps spinning. Can you handle this properly?
  8. Send button should be disabled until some actual text is in the input.
  9. Positioning should be relative to the [Get Help] button. position seems different in the Single-page layout vs Tabbed layout.
  10. Where's the part of the code where we will handle the updated responses from Codaveri?

I have updated for 1-9, about 10, it should be stay in the PR about integration with new Codaveri API, I think

@phungmanhcuong phungmanhcuong force-pushed the mcphung/get-help-enhancement branch 5 times, most recently from 046f203 to 22eea36 Compare November 18, 2024 01:32
@phungmanhcuong phungmanhcuong self-assigned this Nov 18, 2024
@@ -0,0 +1,79 @@
.get-help-page-paper {
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment on lines 209 to 210
id: `course.assessment.submission.liveFeedback.${toCamelCase(suggestion)}`,
defaultMessage: suggestion,
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't do this text to camelCase, use defineMessages instead for suggestions.

@phungmanhcuong phungmanhcuong force-pushed the mcphung/get-help-enhancement branch 10 times, most recently from b160947 to 774d97f Compare November 21, 2024 05:04
Copy link
Contributor

@cysjonathan cysjonathan left a comment

Choose a reason for hiding this comment

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

Please remove all arbitrary values in the tailwind classes.
If you do need to use any, provide justification and clear with me first.

Comment on lines 30 to 37
const getRandomSuggestions = () => {
const suggestionValues = Object.values(suggestionsTranslations);
const shuffled = suggestionValues.sort(() => 0.5 - Math.random());
// TODO: Temporarily change to show no suggestions
return shuffled.slice(0, 0);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't implement your own shuffle, your algorithm is not truly random.

You can use our lodash library's shuffle.

<div className="absolute top-[-4rem] flex justify-center mb-0 w-full flex-row h-[52%] overflow-x-auto">
{suggestions.map((suggestion, index) => (
<Button
key={index}
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't use the index as the key, the translation object itself should have an id.

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, to make it extensible, suggestions can just take in an array of strings as you have done so (since the API would just give you an array of strings).
But don't use the index as key, can just use the suggestion itself as the key.

suggestions: string[];
handleSendMessage: (message: string) => void;
}> = ({ loading, suggestions, handleSendMessage }) => (
<div className="absolute top-[-4rem] flex justify-center mb-0 w-full flex-row h-[52%] overflow-x-auto">
Copy link
Contributor

Choose a reason for hiding this comment

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

Can use this "scrollbar-hidden absolute bottom-full flex p-3 gap-3 justify-around w-full overflow-x-auto", please refrain from using arbitrary values.

{suggestions.map((suggestion, index) => (
<Button
key={index}
className="bg-white mx-1 text-[1.3rem] min-w-[160px]"
Copy link
Contributor

Choose a reason for hiding this comment

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

"bg-white whitespace-nowrap shrink-0"

Comment on lines 88 to 98
.sort((a, b) => a.linenum - b.linenum)
.map((line, index) => ({
text: `Line ${line.linenum}: ${line.feedback}`,
sender: 'Codaveri',
linenum: line.linenum,
timestamp:
index === feedbackFile.feedbackLines.length - 1
? new Date().toISOString()
: null,
isBold: false,
})),
Copy link
Contributor

Choose a reason for hiding this comment

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

Ben also requested to collapse feedback which share the same line, please include that

Comment on lines +48 to +56
const updateFeedbackForQuestion = (draft, questionId, newFeedbacks) => {
draft.feedbackByQuestion[questionId] = {
...getOrDefault(draft.feedbackByQuestion, questionId, {}),
...newFeedbacks,
};
saveStateToLocalStorage(draft);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Your states are not being saved properly, please double-check.

e.g. leave the [Get Help] window in open state, navigate away, then navigate back, the window won't show up as open state.

linenum: line.linenum,
timestamp:
index === feedbackFile.feedbackLines.length - 1
? new Date().toISOString()
Copy link
Contributor

Choose a reason for hiding this comment

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

Use CM's datetime formatters instead of just ISO string please, formatShortDateTime from moment.ts

{loading && (
<ListItem className="justify-start py-0">
<Bubble>
<BeatLoader color="grey" size={8} />
Copy link
Contributor

Choose a reason for hiding this comment

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

Use our existing <LoadingEllipsis /> or write your own, following loading ellipsis example.

- Refactor feedback grouping logic by line number for better readability
- Enhance suggestions display using translations for dynamic content
- Replace react-spinners with a custom loading component (LoadingEllipsis)
- Use moment for consistent timestamp formatting
- Remove react-spinners dependency to streamline the package
@phungmanhcuong phungmanhcuong force-pushed the mcphung/get-help-enhancement branch 2 times, most recently from e23a188 to 1b34a53 Compare November 26, 2024 05:40
- Change text property in LiveFeedbackMessage to always be an array for consistency
- Simplify rendering logic in Message component
- Add error message handling in liveFeedbackReducer for failure cases
- Enhance UI interactions with feedback lines and error notifications
- Removed unused moment import and related date formatting functions.
- Added bgColor property to LiveFeedbackMessage type for dynamic styling of messages.
- Simplified text rendering logic in the Message component for better readability.
- Enhanced reducer logic to include bgColor for different message types like errors and user messages.
- Fixed handling of null linenum in line navigation to prevent unintended behavior.
- Replaced redundant state management with direct use of conversation in GetHelpPage.

return (
<div key={keyString} id={keyString} style={{ position: 'relative' }}>
<Box marginRight={shouldRenderDrawer ? '315px' : '0px'}>
<Box marginRight="0px">
Copy link
Contributor

Choose a reason for hiding this comment

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

change into <Box className="mr-0">. Remember that we're migrating to tailwind, which also means that all styling for any component should be done in tailwind unless it cannot be done (which is, as far as I know, never the case)

client/yarn.lock Outdated
@@ -9371,11 +9371,6 @@ react-sortable-tree-patch-react-17@^2.9.0:
react-lifecycles-compat "^3.0.4"
react-virtualized "^9.21.2"

react-spinners@^0.14.1:
Copy link
Contributor

Choose a reason for hiding this comment

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

the previous commit (still within this PR) adds this library, while this commit deletes it. If this library is not needed at all, you need to not even have it added in any commits in this PR

with that being said, any line that relies on this react-spinners from the previous commit needs to be removed at that commit, not here

sender: 'Student',
timestamp: new Date().toISOString(),
timestamp: moment(new Date()).format(SHORT_DATE_TIME_FORMAT),
Copy link
Contributor

Choose a reason for hiding this comment

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

the naming timestamp has an inference that it will be of type DateTime, but this one is actually of type string. It's not entirely wrong, but I suggest for this timestamp to be stored as new Date() then inside GetHelpPage.tsx, you then use this functionality towards message.timestamp

Also, we have the functionality formatShortDateTime which basically encapsulates what is being done here. I recommend you to search that function within our codebase, then apply it accordingly.

Do the same also for all the similar lines within this page (and also other page, if it exists)

sender: string;
linenum: number | null;
isBold: boolean;
text: string | string[];
Copy link
Contributor

Choose a reason for hiding this comment

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

if you put text as a prop name, other dev will think it to be obviously string; there will be no way the prop name text will be regarded as an array (texts might be, though)

I suggest to just make it one type (string[] should be fitting well with the purpose here), change the prop name to texts or anything that suits what it serves to be, then change everything accordingly (for example, if there's a place where indeed text is singular, change it into [text] then handle the array accordingly)

message: {
sender: string;
linenum: number | null;
isBold: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

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

I saw this props being assigned but never being actually used anywhere. If this prop ended up not being used, just remove it (also actually our consensus is generally to avoid using bold unless necessary. Alternative is usually to explore the variant props in Typography)

</Typography>
)}
{message.text.map((line, index) => (
<Typography key={index} className="text-[1.3rem]">
Copy link
Contributor

Choose a reason for hiding this comment

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

remember not to use index for our key. Using line suffices. Fix it accordingly, and also in all the places in which you put index as value for key


return (
<ListItem
className={`py-0 ${message.sender === 'Codaveri' ? 'justify-start' : 'justify-end'}`}
Copy link
Contributor

Choose a reason for hiding this comment

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

I saw this string Codaveri being used in many places within your PR. Consider to assign a constant, for example, CODAVERI_SENDER or something like that, as Codaveri, then you use that constant instead.

So it will be like message.sender === CODAVERI_SENDER instead of hard-coded string

@@ -142,9 +142,18 @@ const liveFeedbackReducer = function (state = initialState, action) {
case actions.LIVE_FEEDBACK_FAILURE: {
const { questionId } = action.payload;
return produce(state, (draft) => {
const previousConversation = getConversation(draft, questionId);
const errorMessage = {
text: ['An error occurred while processing your request !!!'],
Copy link
Contributor

Choose a reason for hiding this comment

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

If you need this text, don't put it as hard-coded string over here. Use translations instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants