-
Notifications
You must be signed in to change notification settings - Fork 350
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
Make values
optional on PerseusCategorizerWidgetOptions
type
#2123
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@khanacademy/perseus": minor | ||
"@khanacademy/perseus-core": minor | ||
--- | ||
|
||
Make `values` field optional on the `PerseusCategorizerWidgetOptions` type. This will allow us to remove `values` (which represents the correct answer) from the data sent to the client. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,9 +59,9 @@ function getAnswersFromWidgets( | |
categorizer.options?.items && | ||
categorizer.options?.values | ||
) { | ||
const categories = categorizer.options?.categories; | ||
const items = categorizer.options?.items; | ||
const values = categorizer.options?.values; | ||
const categories = categorizer.options.categories; | ||
const items = categorizer.options.items; | ||
const values = categorizer.options.values; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These |
||
answers.push( | ||
...values.map( | ||
(value, index) => | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import {parse} from "../parse"; | ||
import {success} from "../result"; | ||
|
||
import {parseCategorizerWidget} from "./categorizer-widget"; | ||
|
||
import type {CategorizerWidget} from "@khanacademy/perseus-core"; | ||
|
||
describe("parseCategorizerWidget", () => { | ||
const baseWidget: CategorizerWidget = { | ||
type: "categorizer", | ||
version: {major: 0, minor: 0}, | ||
graded: true, | ||
options: { | ||
items: [], | ||
categories: [], | ||
randomizeItems: false, | ||
static: false, | ||
}, | ||
}; | ||
|
||
it("allows `values` to be undefined", () => { | ||
const widget = { | ||
...baseWidget, | ||
options: { | ||
...baseWidget.options, | ||
values: undefined, | ||
}, | ||
}; | ||
const result = parse(widget, parseCategorizerWidget); | ||
expect(result).toEqual(success(widget)); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,13 +28,13 @@ import type {CategorizerPromptJSON} from "../../widget-ai-utils/categorizer/cate | |
import type {PerseusCategorizerWidgetOptions} from "@khanacademy/perseus-core"; | ||
|
||
type Props = WidgetProps<RenderProps, PerseusCategorizerScoringData> & { | ||
values: ReadonlyArray<string>; | ||
values: ReadonlyArray<number>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should have been There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought this might be the case, but I couldn't figure out why it was added at all. It's already included in renderProps, so I thought it might have been for another reason. Glad we can make it number! Do we even need that added on if it's already added via RenderProps? |
||
}; | ||
|
||
type DefaultProps = { | ||
items: Props["items"]; | ||
categories: Props["categories"]; | ||
values: Props["values"]; | ||
values: ReadonlyArray<number>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this necessary if you updated the type of values to be this anyway? |
||
linterContext: Props["linterContext"]; | ||
}; | ||
|
||
|
@@ -79,7 +79,6 @@ export class Categorizer | |
|
||
onChange(itemNum, catNum) { | ||
const values = [...this.props.values]; | ||
// @ts-expect-error - TS2322 - Type 'number' is not assignable to type 'never'. | ||
values[itemNum] = catNum; | ||
this.change("values", values); | ||
this.props.trackInteraction(); | ||
|
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.
Potential concern here: with this change, the
data-schema
types no longer represent the JSON that actually gets persisted. The JSON should always have thevalues
field, but the client won't always receive it.If we wanted to fix this, we would have to decouple the widget prop types from these data-schema types. Though I think maybe they are already pretty much decoupled (in theory) by the
transform
andstaticTransform
functions.transform
renders the widget with public-only data andstaticTransform
renders with public+private data.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 if the JSON should always have the values field, then it might be worth it to fix this. It seems like the data-schema and our contract with users is pretty important, and I'd rather it be as accurate as possible. Aren't we creating different types for the JSON versus what the client is getting though?
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.
Yeah, I agree it's important for the data-schema to accurately reflect the JSON. You are right, the JSON types and the prop types are going to be different in a SSS world. I'll post in Slack with more thoughts.