-
Notifications
You must be signed in to change notification settings - Fork 353
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
Expose a way to get user input from ServerItemRenderer #1753
base: main
Are you sure you want to change the base?
Conversation
Size Change: +581 B (+0.05%) Total Size: 1.29 MB
ℹ️ View Unchanged
|
npm Snapshot: PublishedGood news!! We've packaged up the latest commit from this PR (9482abe) and published it to npm. You Example: yarn add @khanacademy/perseus@PR1753 If you are working in Khan Academy's webapp, you can run: ./dev/tools/bump_perseus_version.sh -t PR1753 |
GeraldRequired Reviewers
Don't want to be involved in this pull request? Comment |
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.
Yay!
const userInput = renderer.getUserInputMap(); | ||
const score = scorePerseusItem(question1, userInput, mockStrings, "en"); |
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.
Scoring split from user input! A red-letter day in history! 🎉
// TODO(LEMS-2461,LEMS-2391): these probably | ||
// need to be removed before we move this to the server | ||
strings: PerseusStrings, | ||
locale: string, |
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 suspect we'll always need the locale for scoring, because of things like decimal separators. But localized strings I agree with you on.
// There seems to be a chance that PerseusRenderer.widgets might include | ||
// widget data for widgets that are not in PerseusRenderer.content, | ||
// so this checks that the widgets are being used before scoring them |
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.
Yes. Our editor doesn't (or hasn't always) cleared out widget configs when they are removed from content
... so there is quite a bit of content that's been published that has unused widget configs in them.
export function scoreWidgetsFunctional( | ||
widgets: PerseusWidgetsMap, | ||
// This is a port of old code, I'm not sure why | ||
// we need widgetIds vs the keys of the widgets object | ||
widgetIds: Array<string>, | ||
widgetIds: ReadonlyArray<string>, |
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.
👍 Thanks.
packages/perseus/src/renderer.tsx
Outdated
* Returns an object mapping from widget ID to perseus-style score. | ||
* The keys of this object are the values of the array returned | ||
* from `getWidgetIds`. | ||
* Grades the content. |
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.
nit: We've been asked to use "score" over "grade". :)
EDIT: Oh, I see that was the original comment from below. Would you mind updating it still?
* Grades the content. | |
* Scores the content. |
@@ -136,6 +139,16 @@ export class ServerItemRenderer | |||
this.props.onRendered(true); | |||
} | |||
} | |||
|
|||
if (this.props.score && this.props.score !== prevProps.score) { |
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.
question: Should we use a deep equality check here instead of simply instance comparison? 🤔 If the score is identical, I guess it could still mean that there are different widgets that are empty and need to be highlighted. I think I answered my own question. 😖
* questionCompleted is used by Radio and LabelImage to change what | ||
* it renders after a learner has checked the correctness of an answer. | ||
* For instance LabelImage disables inputs for correct answers and marks | ||
* incorrect answers so learners can update what they submitted. |
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 like referencing widgets that use the flag as an example, but I think we can word this more generically (like, what should this flag be used for). :)
So this flag is used by the renderer to signal to widgets that the question is done and they can alter what they render to reveal explanations or other information about why the learner's input was wrong, etc.
Your comment is basically good, I guess I would just suggest that we remove the wording that implies that only Radio and LabelImage use this (they do! but in the future they may not be the only ones). Sorry, I'm probably splitting hairs.
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.
Also, it might be good to add a comment something like this to the WidgetProps<T>
type as it has this flag too and it'd be helpful within widgets to be able to see that prop's intended usage.
* after a learner has clicked the "check" button. I don't think this could | ||
* still be used though, because the "check" button is disabled while there | ||
* are empty widgets. | ||
*/ | ||
questionHighlightedWidgets: ReadonlyArray<any>; |
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's correct. And to be really clear, it's an array of widget IDs (strings). Could you try changing this to ReadonlyArray<string>
Summary:
Webapp PR
I'm trying to tread lightly, maybe being overly cautious at the expense of keeping too much old code around. I tried to make everything we can get rid of after the move with
@deprecated
.Basically this should expose everything we need to move the actual scoring process out of ServerItemRenderer and the React tree. We now have
getUserInput
onServerItemRenderer
andscorePerseusItem
which is a non-React, pure function that returns a score.Next step is to replace uses of
scoreInput
in Webapp withscorePerseusItem
; then we can come back and delete a lot of this legacy code 🤞Issue: LEMS-2389
Test plan:
After the swap in Webapp, we should be able to complete an exercise with
scorePerseusItem
and everything else will work the same.