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
[Student Libraries] Exporter UI #31303
Conversation
<Body> | ||
<PadAndCenter> | ||
<div style={styles.libraryBoundary}> | ||
<Heading1>Functions as a Library</Heading1> |
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.
Maybe "Export functions as a library?" (also posted in #student-created-libraries where more of the UI review is happening)
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.
✔️
style={styles.textarea} | ||
placeholder="Write a description of your library" | ||
/> | ||
{this.state.selectedFunctionList.map(selectedFunction => { |
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.
When 'publish' is clicked, only the functions whose boxes are checked should be in "selectedFunctionsList."
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 didn't add this originally, but we'll probably need two lists of functions, the original functions parsed from the code, and the list of functions that have been checked.
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.
Whoops - forgot to only send the selected functions through. 🤦♀️ Fixing.
I don't understand your second comment though. Can you elaborate?
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.
Haha it was meant to clarify the first comment, but sounds like it wasn't necessary (or helpful lol).
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.
For the createLibrary - I swapped out the full list of functions to be just the selected ones. Can you confirm that's the correct usage? (Latest commit)
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.
👍 Thank you!
import {connect} from 'react-redux'; | ||
import {hideLibraryCreationDialog} from '../shareDialogRedux'; | ||
import libraryParser from './libraryParser'; | ||
import LibraryClientApi from './LibraryClientApi'; | ||
import i18n from '@cdo/locale'; | ||
import PadAndCenter from '../../../templates/teacherDashboard/PadAndCenter'; | ||
import {Heading1, Heading2} from '../../../lib/ui/Headings'; |
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.
Might be good to use @cdo format for these two as well given the three levels of ../.
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.
✔️
Make sure you add tests! |
return ( | ||
<div key={keyIndex++} style={styles.functionItem}> | ||
<input | ||
type="checkbox" | ||
style={styles.largerCheckbox} | ||
disabled={comment.length === 0} | ||
onClick={this.validateInput} | ||
value={keyIndex} |
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 does this do? (and why is the default -1?)
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.
Good question! This was a workaround for handling functions that have the same name/comments. Since we can't rely on unique values to connected the selected checkbox to the list of functions, I've shifted to using indices. Because javascript .map goes over the array items in order, we can assign each item created an index so that we can then track that index back to the function it is meant to represent.
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.
It is initialized at -1
because it increments on each item created, so it has to start at -1
so that it starts zero indexed. I don't love this solution, but I couldn't really figure out another way to do while still using a map. I'm open to suggestions!
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.
Don't love that it starts at -1?
You should be able to increment the counter at the end of .map instead of the beginning of .map. Then you can start it at 0.
let libraryJson = libraryParser.createLibraryJson( | ||
this.state.librarySource, | ||
this.state.selectedFunctionList, | ||
selectedFunctionList, | ||
this.state.libraryName |
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.
Were you planning to add libraryDescription here?
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, still in progress.
@jmkulwik PTAL - while implementing tests I realized that there are something in the state that are probably best suited to not be part of state. I am tracking an work item now to fix that at a later point and add some more tests, but I don't think it's worth blocking this PR on it. |
{comment.length === 0 && ( | ||
<p style={styles.alert}> | ||
This function cannot be exported until you add a comment to | ||
it. |
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.
i18n
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 was planning to hold off on i18n until we had a better idea if these were the final phrasings. Do you think we're there?
if (element.type === 'checkbox' && element.checked) { | ||
selectedFunctionList.push(this.state.sourceFunctionList[element.value]); | ||
} | ||
if (element.type === 'textarea') { |
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: (I don't feel too strongly about this) This seems like it would be more maintainable as a check by class name rather than type. i.e. it's not too unlikely that we'd add another textarea somewhere.
@jmkulwik PTAL - thanks! |
expect(wrapper.find(CHECKBOX_SELECTOR).last()).to.be.disabled(); | ||
}); | ||
|
||
it('displays loading while in the loading state', () => { |
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.
Awesome
@@ -130,10 +175,16 @@ describe('Library parser', () => { | |||
|
|||
let expectedFunctions = `${firstFunctionName}: ${firstFunctionName},${secondFunctionName}: ${secondFunctionName}`; |
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.
Maybe add a test with a non-empty description
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.
displayFunctions = () => { | ||
if (!this.state.loadingFinished) { | ||
return <div>Loading...</div>; | ||
return <div id="loading">Loading...</div>; |
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.
If you get the chance, it would be nice to make this a spinner instead of Loading...
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.
Description
Part of the Student Libraries work.
When the user goes to 'Share' -> 'Share as Library' this is what they see.
Note:
Not i18n until wording confirmed.
Note: Can't submit with an empty description or with no checkboxes checked. Can't check a checkbox that doesn't have a comment.
Links
Testing story
Manually tested.
Reviewer Checklist: