This is the Technical Approach doc for Approach Memo: Studio Copy & Paste for Content Reuse Across Courses

Deliverable: A lightweight functionality that enables authors to reuse components, units, subsections and sections by sharing directly from one course to another. The copy/paste functionality will also work for static pages. For this first MVP, the content is copied as a one-time action, and any future edits made to either copy won’t be synced. However, it is possible to edit the component independently in its new environment.

UX: Studio Copy/Paste

We’re going to lean on the common copy-paste metaphor, by introducing the idea of a Studio copy/paste. You can copy content at various levels of granularity (components, units, subsections, sections), and then paste it into a different location within the same course, or into an entirely different course.

Final Figma Frames: https://www.figma.com/file/y2qfzidTxxfYK8ONgyT7KP/Modular-Learning-Wireframes?node-id=823%3A778&t=TEJeqjOoWnxaYltO-1

Summary of New UI elements


Additional Scope details:

Alternative UX Considered

An earlier concept involved using a set of menus that would allow you to select the destination course/location an item would be copied into, drilling down until you got to the location you wanted:

The Clipboard approach is preferred we believe it provides a simpler and more intuitive interface, and we don’t have to deal with the complexity of filtering for people who have access to thousands of courses.

Implementation Challenges

Static Asset Dependencies

XBlock content often has static asset dependencies (e.g. images, subtitles, etc.). Our approach:

Explicit vs. implicit static asset files

Some static assets are explicitly uploaded and tracked in Studio’s Files and Uploads page, but some are implicitly managed by individual XBlocks, such as manually uploaded SRT files. I believe ORA2 also has something along these lines, though I forget the specifics. We have to copy both explicit and implicit asset files in order to not break content, but how do we report that in the preview? Some possible approaches:

  1. Proposed Solution: Only report the things that are in Files and Uploads.

  2. Alternative: Display all assets being copied, including the ones local to specific XBlocks.

  3. Alternative: Display both items but explicitly separate them in the presentation to the user.

I’m proposing we go with #1 because the assets that are local to a given XBlock can’t actually have any conflicts, so we don’t need to talk about them. We can conceptually think of them as a part of the XBlock in that sense, and it will reduce confusion for the course author.

Note that I’m just making up vocabulary on the fly here, and “explicit vs. implicit static assets” aren’t really a thing that Studio talks about. Studio generally uses the language of “Files” for the explicitly uploaded ones.

Special Case: python_lib.zip

Problem: How do we handle ProblemBlocks that depend on libraries that are bundled in a course’s python_lib.zip file?

Content Incompatibility and Reconciliation

The content being copied may not be fully compatible with the course’s metadata. For example:

Possible solutions

Note that these are not mutually exclusive, and we may choose some mix of approaches depending on the specific situation.

  1. Add APIs to support reconciliation/adjustment of values before they’re inserted into a course.

  2. Fall back to reasonable default settings, e.g. if the content group doesn’t exist for the course, we could set that value to be blank.

  3. Adjust the course settings, either automatically or with some kind of confirmation, e.g. add XBlock types to the course’s advanced settings.

  4. Block pasting entirely if requirements are not met.

  5. Paste with minimal checking, but surface incompatibilities via Studio’s editing interface so that users can be made aware of the issues and correct them. TODO: Investigate what happens today in Studio’s interface when content is imported with some of these incompatibilities.

No matter what, we will need some extensible API for different content types to implement to enable things like determining which assets they need. We can create an EnsureDestinationCompatibility API that will allow content types to reconfigure themselves automatically. The API itself shouldn’t directly use the XBlock runtime.

Current Proposal

For the initial MVP, allow incompatible items to be pasted, and surface the errors in the Studio UI.

Performance when Copying or Pasting Large Content

A Section might be so large that it takes a prohibitive amount of time to serialize into OLX in order to be copied. This needs to be tested.

Copy, Modify/Delete, and Paste

Say a piece of content was copied and is in the clipboard for a long period of time (days or even weeks). Since that time, modifications have been made to the original content or the static assets that have been referenced by that content.

Proposal: We completely copy the OLX and associated assets at the time the “Copy” button is pressed.

Library Content Blocks

LibraryContentBlock is complex and ends up pulling copies of all the content it references into the Modulestore for that course. I’m not sure if this will Just Work if we copy the OLX for the LibraryContentBlock across courses, or if there’s other loading that needs to happen.

Technical Details

Future Possibilities

There are other concepts that are sort of technically adjacent to this one. We won’t necessarily implement these using the same foundation, but we should try to keep them in the back of our minds while building this in case there are easy wins:

Milestones

M1: Basic Component Copy-Paste Proof-of-Concept

M1 gets the very basic functionality out there in a way that’s testable by users, but is not really releasable to a production environment.

For final list of stories and links to UX design etc. see M1 on GitHub: https://github.com/openedx/modular-learning/issues/1

M2: Releasable Component Copy-Paste with Asset Dependencies

M2 gets us to something that’s useful enough to release to end users, even if it has obvious gaps in functionality and some edge cases where it might be incompatible (e.g. content group settings).

M3: Unit Support

M3 gets us to something broadly releasable to users.

M4: Subsection Support

M4 gets to some of the really big copy-paste functionality for moving stuff between courses, but it also represents more unknowns and possibilities for scope creep.

M5: Section Support

M5 would be the last piece, though there might be other experience fine-tuning work that gets moved here as well.

Estimated development timeline