Support pasting units from course into libraries - #36516
Conversation
|
Thanks for the pull request, @bradenmacdonald! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review. 🔘 Get product approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. DetailsWhere can I find more information?If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources: When can I expect my changes to be merged?Our goal is to get community contributions seen and reviewed as efficiently as possible. However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
8403d38 to
b922d04
Compare
rpenido
left a comment
There was a problem hiding this comment.
LGTM 👍
Thank you for your work, @bradenmacdonald!
- I tested this using the instructions from openedx/frontend-app-authoring#1812
- I read through the code
- I checked for accessibility issues
- Includes documentation
ormsbee
left a comment
There was a problem hiding this comment.
Looks good! Just some minor questions/requests. Thank you!
| XBlock.load_class(block_type) # Will raise an exception if invalid | ||
| block_class = XBlock.load_class(block_type) # Will raise an exception if invalid | ||
| if block_class.has_children: | ||
| raise IncompatibleTypesError("XBlocks with children are not supported in content libraries") |
There was a problem hiding this comment.
Please add the block type and block_id in the error being raised, so that it's easier to pinpoint the problematic content.
| olx_node = etree.fromstring(olx_str) | ||
| title = olx_node.attrib.get("display_name") | ||
| # Slugify the title and append some random numbers to make a unique slug | ||
| block_id = slugify(title, allow_unicode=True) + '-' + uuid4().hex[-6:] |
There was a problem hiding this comment.
This is fine, but in the longer term, do you think it's worthwhile to add this concept to the Learning Core layer (find me some key that starts with this and doesn't collide)? At that layer, we could use things like the primary key to disambiguate them more succinctly.
There was a problem hiding this comment.
This is fine, but in the longer term, do you think it's worthwhile to add this concept to the Learning Core layer (find me some key that starts with this and doesn't collide)?
Yes, that would be a nice improvement!
| # Generate a block_id: | ||
| try: | ||
| olx_node = etree.fromstring(olx_str) | ||
| title = olx_node.attrib.get("display_name") |
There was a problem hiding this comment.
If this is pulling directly from the OLX, is it going to end up having a lot of blank values for the display name? Do we need to special case those properly so they say things like "problem_{number}"? Or does the OLX already have that encoded into it at this point?
There was a problem hiding this comment.
Good point, I think we should be more defensive here and not assume what the OLX may or may not have for display_name. I've updated it to fall back on the localized block name if there's no display name, which I was already doing for units anyways.
| """ | ||
| from openedx.core.djangoapps.content_staging import api as content_staging_api | ||
| if not content_staging_api: | ||
| raise RuntimeError("The required content_staging app is not installed") |
There was a problem hiding this comment.
Is it even possible to not install the content_staging app at this point? Is the concern that this could be called from the LMS instead of Studio?
There was a problem hiding this comment.
Technically it's an app plugin, but in practice it's always installed in the CMS unless the install is corrupted. I'll remove these warnings. We do have to continue importing it within these functions though, unless/until we resolve the fact that the content_libraries API is sometimes imported into the LMS.
|
|
||
|
|
||
| class LibraryXBlockMetadataSerializer(serializers.Serializer): | ||
| class PublishableItemSerializer(serializers.Serializer): |
ChrisChV
left a comment
There was a problem hiding this comment.
Looks good! Could you fix the conflicts to merge this?
c45ed3e to
7ddc572
Compare
7ddc572 to
844a4b5
Compare
|
Rebased. |
|
2U Release Notice: This PR has been deployed to the edX staging environment in preparation for a release to production. |
|
2U Release Notice: This PR has been deployed to the edX production environment. |
1 similar comment
|
2U Release Notice: This PR has been deployed to the edX production environment. |
* fix: don't allow pasting xblocks with children into libraries * fix: IntegrityError: "Column 'md5_hash' cannot be null" * feat: allow pasting a unit from a course into a library * feat: auto-generate a nice block_id when pasting into a library * test: add test for pasting unit from course into library * fix: better handle potentially missing display_names during paste * chore: clarifications and import cleanups
* fix: don't allow pasting xblocks with children into libraries * fix: IntegrityError: "Column 'md5_hash' cannot be null" * feat: allow pasting a unit from a course into a library * feat: auto-generate a nice block_id when pasting into a library * test: add test for pasting unit from course into library * fix: better handle potentially missing display_names during paste * chore: clarifications and import cleanups
Description
This PR provides the backend API updates requires so that users can paste a unit from a course into a library.
It also fixes the pasting code so that the
block_id(used in the URL) is now generated from the title of the copied thing, which creates much nicer usage keys / URLs while still avoiding conflicts.It also cleans up the serializers and makes them use more common code.
It also fixes the following bugs 🐛:
fix: IntegrityError: "Column 'md5_hash' cannot be null"def_keyfrom the REST API responseSupporting information
Relates to openedx/frontend-app-authoring#1647 though this is technically the opposite of that. Pasting into a course proved too complicated to implement for now because it requires converting a container to an XBlock.
Testing instructions
Test using openedx/frontend-app-authoring#1812
Deadline
ASAP
Other information
Private ref: FAL-4067