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

Add "static" toggle to Interactive Graph widget #1503

Merged
merged 12 commits into from
Aug 13, 2024

Conversation

benchristel
Copy link
Member

@benchristel benchristel commented Aug 8, 2024

Summary:

Some of our widgets (e.g. Radio) have a "static" mode which can be toggled on
in the exercise editor. When a widget is in static mode, the "answer" to the
widget is displayed, the widget is not graded, and the learner cannot alter
the widget's state.

Content creators need to be able to set interactive graphs to static mode so
that graphs can be added to hints, to demonstrate the solution steps for an
exercise. Previously, we implemented a special "hint mode" for interactive
graphs to accommodate this use case. Hint mode was based on a couple faulty
assumptions:

  • We did not clearly understand what static mode was or when it was turned on.
    We confused static mode with the "read only" state of a widget, which occurs
    when a learner has successfully answered the question. Similar to static mode,
    the read-only state makes the widget non-interactable. However, while static
    mode is configurable by content creators, read-only state is not; it is set
    or unset dynamically, based on the learner's progress through an exercise.
  • We assumed that graphs in hints would always be non-interactable, so we
    turned on hint mode automatically in hints (and turned it off in question
    stems) rather than giving content creators a manual toggle. This assumption
    turned out to be incorrect; we now know of at least one question where a hint
    contains a graph that the learner is supposed to be able to manipulate. See:
    https://khanacademy.slack.com/archives/C067UM1QAR4/p1723045477082029

Hint mode (which this feature replaces) was never released to content creators,
so we are okay to drop support for it.

This PR removes hint mode and adds a "static" toggle to the Interactive
Graph widget editor. It builds on work that @nicolecomputer did in
#1457. Her feature branch is merged into
this one.

Issue: LEMS-2251, LEMS-2053, LEMS-2054

Test plan:

  • Deploy this to a ZND
  • Create an exercise in the Test Everything course
  • Create a static interactive graph
  • Verify that the preview is non-interactable (with mouse and keyboard) when
    the "static" toggle is on, and interactable when "static" is off.
  • Save and publish the exercise.
  • Go through the exercise as a learner and verify that you cannot manipulate
    the static graphs.
  • Verify that the presence of a static graph does not affect how a question is
    graded.

@benchristel benchristel self-assigned this Aug 8, 2024
@khan-actions-bot khan-actions-bot requested a review from a team August 8, 2024 19:47
@khan-actions-bot
Copy link
Contributor

khan-actions-bot commented Aug 8, 2024

Gerald

Required Reviewers
  • @Khan/perseus for changes to .changeset/gentle-dragons-hide.md, packages/perseus/src/hint-renderer.tsx, packages/perseus/src/renderer.tsx, packages/perseus/src/types.ts, packages/perseus/src/__tests__/renderer.test.tsx, packages/perseus/src/mixins/widget-prop-denylist.ts, packages/perseus/src/widgets/interactive-graph.tsx, packages/perseus-editor/src/__stories__/editor-page-with-storybook-preview.tsx, packages/perseus/src/widgets/__stories__/expression.stories.tsx, packages/perseus/src/widgets/__stories__/interactive-graph.stories.tsx, packages/perseus/src/widgets/__testdata__/interactive-graph.testdata.ts, packages/perseus/src/widgets/__tests__/passage.test.tsx, packages/perseus/src/widgets/interactive-graphs/interactive-graph-question-builder.ts, packages/perseus/src/widgets/interactive-graphs/mafs-graph.test.tsx, packages/perseus/src/widgets/interactive-graphs/mafs-graph.tsx, packages/perseus/src/widgets/interactive-graphs/stateful-mafs-graph.test.tsx, packages/perseus/src/widgets/interactive-graphs/stateful-mafs-graph.tsx

Don't want to be involved in this pull request? Comment #removeme and we won't notify you of further changes.

Copy link
Contributor

github-actions bot commented Aug 8, 2024

npm Snapshot: Published

Good news!! We've packaged up the latest commit from this PR (d15fa13) and published it to npm. You
can install it using the tag PR1503.

Example:

yarn add @khanacademy/perseus@PR1503

If you are working in Khan Academy's webapp, you can run:

./dev/tools/bump_perseus_version.sh -t PR1503

Copy link
Contributor

github-actions bot commented Aug 8, 2024

Size Change: +45 B (+0.01%)

Total Size: 855 kB

Filename Size Change
packages/perseus/dist/es/index.js 414 kB +45 B (+0.01%)
ℹ️ View Unchanged
Filename Size
packages/kas/dist/es/index.js 38.3 kB
packages/kmath/dist/es/index.js 4.27 kB
packages/math-input/dist/es/index.js 78.2 kB
packages/math-input/dist/es/strings.js 1.79 kB
packages/perseus-core/dist/es/index.js 1.48 kB
packages/perseus-editor/dist/es/index.js 276 kB
packages/perseus-linter/dist/es/index.js 21.8 kB
packages/perseus/dist/es/strings.js 3.29 kB
packages/pure-markdown/dist/es/index.js 3.67 kB
packages/simple-markdown/dist/es/index.js 12.4 kB

compressed-size-action

@benchristel benchristel requested a review from Myranae August 8, 2024 19:52
@Myranae
Copy link
Contributor

Myranae commented Aug 8, 2024

Haven't finished properly reviewing, but I believe some of this code is code I also changed in my bug fix PR. It's been approved, but I wanted to manually test before landing. Hoping to do that today, just ran into some local dev server / ZND issues. I'll totally update my PR if this one moves forward first though :)

@benchristel
Copy link
Member Author

@Myranae I'll wait for you to land your PR. I need to test this on a ZND before landing it anyway.

@Myranae
Copy link
Contributor

Myranae commented Aug 8, 2024

@benchristel It's landed :)

Copy link
Collaborator

@jeremywiebe jeremywiebe left a comment

Choose a reason for hiding this comment

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

Cool. I was initially surprised by the size of the PR (number of files touched) but most of that is removing hintMode. I'm pretty happy we can use static mode and not introduce another new concept (assuming it all works out). Thanks Ben!

@@ -45,11 +45,11 @@ export type MafsGraphProps = {
labels: InteractiveGraphProps["labels"];
state: InteractiveGraphState;
dispatch: React.Dispatch<InteractiveGraphAction>;
hintMode: boolean;
static: boolean | null | undefined;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure if types from other uses of static force this, but can we make this static: boolean | undefined? I think there are many places that use this X | null | undefined pattern, but in reality, we rarely distinguish between null and undefined.

This is a nitpicky thing, but it's another place where the type is broader/more complicated for no reason.

Copy link
Member Author

Choose a reason for hiding this comment

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

The type boolean | null | undefined comes from WidgetProps, so I had to use the same type here.

I don't really feel comfortable changing WidgetProps, since it's so widely used (and it's one of our few defenses against writing widgets that can't handle production data).

Comment on lines 18 to 22
// The name isStatic (instead of static) avoids a collision with the
// `static` keyword in ES6. `static` is not a valid variable name, so
// naming this `isStatic` allows the object to be destructured without
// renaming the resulting variables.
isStatic: boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Guess we'll want to avoid having a Perseus concept named "const" then, eh? 😂

@benchristel benchristel force-pushed the benc/static-interactive-graphs branch from 3e33577 to 81db6a7 Compare August 8, 2024 23:11
Copy link

codecov bot commented Aug 8, 2024

Codecov Report

Attention: Patch coverage is 72.41379% with 8 lines in your changes missing coverage. Please review.

Project coverage is 70.61%. Comparing base (720e3bf) to head (d15fa13).

Files Patch % Lines
...widgets/interactive-graphs/stateful-mafs-graph.tsx 42.85% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1503      +/-   ##
==========================================
+ Coverage   70.00%   70.61%   +0.61%     
==========================================
  Files         514      517       +3     
  Lines      106133   106174      +41     
  Branches     7629    10875    +3246     
==========================================
+ Hits        74296    74974     +678     
+ Misses      31720    31200     -520     
+ Partials      117        0     -117     

Impacted file tree graph

Files Coverage Δ
packages/perseus/src/hint-renderer.tsx 90.96% <ø> (-0.06%) ⬇️
...ackages/perseus/src/mixins/widget-prop-denylist.ts 100.00% <ø> (ø)
packages/perseus/src/renderer.tsx 93.80% <100.00%> (+1.28%) ⬆️
packages/perseus/src/widgets/interactive-graph.tsx 51.05% <100.00%> (+0.14%) ⬆️
...ctive-graphs/interactive-graph-question-builder.ts 100.00% <100.00%> (ø)
...seus/src/widgets/interactive-graphs/mafs-graph.tsx 99.42% <100.00%> (ø)
...widgets/interactive-graphs/stateful-mafs-graph.tsx 88.96% <42.85%> (-4.98%) ⬇️

... and 125 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 720e3bf...d15fa13. Read the comment docs.

@Myranae
Copy link
Contributor

Myranae commented Aug 9, 2024

Doing some manual testing on this, I noticed the hints-renderer stories related to interactive graph hint mode don't work anymore because hint mode isn't a thing and graphs don't automatically become static when added as a hint. As a result, we may want to delete all the interactive graph stories from the Hints Renderer stories section, especially since we now have static graph stories instead. This story and all the interactive graph ones under it I mean.

@benchristel
Copy link
Member Author

@jeremywiebe @Myranae I realized I missed a crucial part of this feature, which is displaying the correct answer instead of the start coords when the graph is in static mode. So I'll have to ask for another review.

I'd really like Nicole's eyes on this when she's well again, because I suspect she's already done the research to figure out how displaying the correct answer is supposed to work. I've got a solution, but I'm not sure it follows established patterns.

@benchristel benchristel force-pushed the benc/static-interactive-graphs branch from c3f51a8 to 02985f3 Compare August 9, 2024 20:20
@benchristel benchristel force-pushed the benc/static-interactive-graphs branch from 02985f3 to 0f2821e Compare August 13, 2024 21:50
Copy link
Collaborator

@jeremywiebe jeremywiebe left a comment

Choose a reason for hiding this comment

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

This is great. LGTM!

@@ -1352,30 +1352,6 @@ describe("renderer", () => {
expect(el).not.toBeNull();
});

it("should force the widget to be non-static if it has a problem number", () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Really glad we don't need to further commit to this hack. 😅

.build();
result["widgets"] = {
...result["widgets"],
"radio 1": {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hrm... seems like we now we need a radioQuestionBuilder() 😃

@@ -128,5 +129,15 @@ export const StatefulMafsGraph = React.forwardRef<
graph.startCoords,
]);

if (props.static) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This becomes obvious fairly quickly as I read the code, but could you leave a comment here that if we're in static mode we display the correct answer? (unless you don't feel that's necessary)

@benchristel benchristel changed the title Add "static" toggle to Interactive Graph widget Add "static" toggle to Interactive Graph widget Aug 13, 2024
@benchristel benchristel changed the title Add "static" toggle to Interactive Graph widget Add "static" toggle to Interactive Graph widget Aug 13, 2024
@benchristel benchristel merged commit f083200 into main Aug 13, 2024
20 of 27 checks passed
@benchristel benchristel deleted the benc/static-interactive-graphs branch August 13, 2024 23:33
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