-
Notifications
You must be signed in to change notification settings - Fork 480
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 help and tips to Code Bridge #58684
Conversation
@@ -84,7 +84,7 @@ const CodeEditor: React.FunctionComponent<CodeEditorProps> = ({ | |||
|
|||
return ( | |||
<div id="code-editor"> | |||
<div ref={editorRef} className={classNames('codemirror-container')} />; | |||
<div ref={editorRef} className={classNames('codemirror-container')} /> |
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 just removes a rogue ;
that was showing up under the editor
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 good, a couple questions. Pulled, reseeded, and tested and seems to be working great!
dashboard/config/levels/custom/pythonlab/Allthethings Python Lab 1.level
Outdated
Show resolved
Hide resolved
<form className={moduleStyles.dropdownContainer}> | ||
<ul> | ||
{panelOptions().map(panel => { | ||
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.
Nit: If this map function just returns the list item, I think we can actually remove the function's outer curly brackets and explicit return
keyword.
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 get errors when I do that. I believe the reason is this is inline code rather than a function, and any code inside the html needs to be surrounded by curly braces.
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 errors are you getting? I was curious and tried modifying locally and it seems to work. You should be able to remove the curly braces and return
- and the return statement's ;
, which I missed initially!
I believe you only need the curly braces and return if the arrow function includes other steps.
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.
oh I misunderstood what you were saying. I thought you meant remove the curly braces around panelOptions().map...
. Updated to remove them from the inner function.
panelOptions.push(Panels.HelpAndTips); | ||
} | ||
return panelOptions; | ||
}; |
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.
Does this need to be a function or could panelOptions
just be defined as an array? Is there a need to recalculate the options each time panelOptions()
is called or would it be sufficient to do it once?
Going a step further, would it be worth memoizing panelOptions
so that it only re-calculates when there are changes to mapReference
or referenceLinks
?
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.
The reason to keep it as a function is we could switch levels and go from having to not having help and tips, and want to update accordingly.
It's a pretty cheap operation, so I don't think we need to memoize. The react docs say you don't need to memoize for cheap operations.
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.
Sounds good to me! These hooks are still pretty new to me, so I've been trying to test my understanding of how (and why) to use them. Thanks for explaining!
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 ended up changing panelOptions
to be a state value instead, because I found a bug where if you switch levels and were previously on a panel that does not exist on the new level it will still show as your selected panel, but be blank. So I needed to add a useEffect
that depended on the panel options changing.
case Panels.HelpAndTips: | ||
return <HelpAndTips />; | ||
} | ||
}; |
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.
In your Start Over PR, you used useCallback
for functions like resetToStartSource
and onClickStartOver
. Could we do the same thing here to avoid re-creating this function unless the dependencies change?
I have the same question for changePanel
and renderHeaderButton
in this 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.
I'm pretty sure this can be a statically wired dispatch lookup instead.
Move it outside the component and name as:
const getCurrentPanel = {
[Panels.Instructions] : InstructionsView,
[Panels.HelpAndTips] : HelpAndTips
}
Then call it as:
{ getCurrentPanel[currentPanel]() }
(annoyingly, react will not render <CurrentPanel[currentPanel] />
(AFAIK), so we need the janky syntax)
Or, to make it prettier, but less compact:
const CurrentPanel = getCurrentPanel[currentPanel]
...
<CurrentPanel/>
Or, if you still want it inline:
const CurrentPanel = useMemo(() => {
const panelLookup = {
[Panels.Instructions] : InstructionsView,
[Panels.HelpAndTips] : HelpAndTips
}
return panelLookup[currentPanel]
}, [currentPanel]);
...
<CurrentPanel/>
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'll update this to be a static lookup.
To the question on useCallback
, the reason I added it around the start over logic was because I was seeing some issues with unexpected resets of the project code due to us firing a callback too often. However, I probably was overly cautious and didn't clean up ones that didn't need to be wrapped in useCallback.
…ab 1.level Co-authored-by: Mike Harvey <43474485+mikeharv@users.noreply.github.com>
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.
Curious about my question of removing the return
, but definitely not a blocker!
I'm curious about some broader architectural questions. I see that we have added some support to Lab2 for this, but the component itself lives in CodeBridge. Do we consider this work a Lab2 feature? |
This PR enables editing and showing help and tips in Python Lab. The ability to see help and tips is enabled in Web Lab 2 as well, but for now I'm keeping level editing changes scoped to Python Lab.
I made a rough approximation of the figma version of help and tips. It is a dropdown on what was previously only the instructions panel which will only show up if the level has help and tips. I've renamed the instructions component "Info Panel" since it now encompasses more than just instructions.
We did not have a component like the one in the figma (an icon-only dropdown button), so I patched one together using the design system
Button
components and some copied css from the design system dropdown components. Since this is still an approximate UI I didn't spend time perfecting it.Figma
Current UX
May-16-2024.09-20-34.mp4
The hover color is light gray because that is the default in the design system.
Links
Testing story
Tested locally.
Follow-up work
If this is the final design, there is some polish work to do on the dropdown.
PR Checklist: