Skip to content
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

[SE-4650] OEP-15 - add support for course-wide custom resources #28411

Merged
merged 1 commit into from
Oct 4, 2021

Conversation

ha-D
Copy link
Contributor

@ha-D ha-D commented Aug 5, 2021

Description

Intention

This PR implements OEP-15, i.e., enabling the user to add global course-wide scripts rather than having to define them separately for every XBlock. Having such a feature allow us to integrate third-party libraries such as ReadSpeaker and Gamalon which have been requested by our clients.

Approach

As suggested in the OEP, two new fields are added to Advanced Settings allowing the staff to specify a list of JS and CSS resources which they want to be included in all pages of the course.

These resources are rendered in the base templates, which will allow them to be included in all course pages.

However, for the micro-frontend React UI things will need to be a little different. There are two main things consider here:

  • In the React UI, units (and all XBocks inside) are rendered in an iframe. This means scripts and styles added to the parent frame won't work for the XBlocks rendered inside the iframe and vice verca. And so if we want the scripts/styles to be available in both contexts we will have to add them to both.
  • Since the React UI is not rendered with Django templates, it will need to be able to fetch the custom resource URLs via an API call and include them in the page dynamically.

The custom JS/CSS resources are included in the CourseInfoSerializer and will be available to the React UI when it is fetching the course metadata via the API. A future PR on the frontend code will use this and add the resources to the page.
As for the content inside the iframes, they are rendered using templates in django and the changes made for the legacy UI will also work for them.

The changes required for the frontend are available in frontend-app-learning#581

Points of possible debate

  • The OEP only mentions adding support for course-wide scripts (JS) and not styles (CSS). I've decided to also allow adding CSS here since a it's quite common for third-party Javascript libraries to have accompanying stylesheets which also need to be added to the page.

  • I've used the names Course-wide JS and Course-wide CSS for these fields. I personally preferred it over the term global, let me know if you think otherwise or if you have other suggestions.

  • For the React UI, including the scripts/styles twice (once in the parent frame and once in the iframe) is obviously not ideal performance-wise. However, I think the purpose of this OEP was to enable a wide variety of scripts to run and these could be targeting either XBlock content or the course page itself depending on the use-case (correct me if I'm wrong), which will mean the scripts need to be included in both places. Another possible solution could be to have three separate options available for the user:

    • Scripts/Styles to be used in the legacy UI
    • Scripts/Styles to be used in the parent frame of the React UI
    • Scripts/Styles to be used in the iframe's of the React UI

    I feel like it's not worth the extra complexity though

Testing Instructors

Sandbox Link: LMS / Studio

  1. Login to the studio (user: staff@example.com pass: edx) and open the Advanced Settings for the demo course.
  2. Find the Course-wide Custom JS and Course-wide Custom CSS fields and add sample resources to test with. These could be external URLs or files added in the Files and Uploads page.
  3. Visit the any course page (e.g., courseware, discussions, progress, etc. ) and these scripts should be working

(You can skip steps 1 and 2 and use the scripts I've already added. The script will show you a toast message on the upper left corner of the page.)

Reviewers

@openedx-webhooks openedx-webhooks added needs triage open-source-contribution PR author is not from Axim or 2U labels Aug 5, 2021
@openedx-webhooks
Copy link

openedx-webhooks commented Aug 5, 2021

Thanks for the pull request, @ha-D! I've created OSPR-5952 to keep track of it in JIRA, where we prioritize reviews. Please note that it may take us up to several weeks or months to complete a review and merge your PR.

Feel free to add as much of the following information to the ticket as you can:

  • supporting documentation
  • Open edX discussion forum threads
  • timeline information ("this must be merged by XX date", and why that is)
  • partner information ("this is a course on edx.org")
  • any other information that can help Product understand the context for the PR

All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here.

Please let us know once your PR is ready for our review and all tests are green.

@ha-D ha-D marked this pull request as draft August 5, 2021 21:23
@ha-D ha-D force-pushed the hadi/se-4650/oep-15 branch 7 times, most recently from 79158c8 to 4fbb1a8 Compare August 8, 2021 19:05
@ha-D ha-D marked this pull request as ready for review August 8, 2021 21:18
@ha-D ha-D requested a review from a team August 8, 2021 21:18
@natabene
Copy link
Contributor

natabene commented Aug 9, 2021

@ha-D Thank you for your contribution. Please let me know once it is ready for our review.

Copy link
Contributor

@nizarmah nizarmah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two main points regarding the "Points of possible debate".

The main motivation of the OEP is to "facilitate research and experimentation". Accordingly, I agree with the following two points you mentioned:

  • Including the script in both the parent frame and in the iframe is beneficial because it would provide educators to different parts of the Open edX Platform, instead of limiting them to the vertical course content.
  • Complicating things by separating the different domains where the content can be injected isn't necessary because the research and experimentation can prevent certain actions unless the necessary conditions are met.

Accordingly, I'm going to go ahead and provide my approval to this pull request since I've already:

  • test the changes as you suggested in the pull request
  • read through the code

Nice work 👍🏼

lms/templates/main.html Outdated Show resolved Hide resolved
@openedx-webhooks openedx-webhooks added waiting on author PR author needs to resolve review requests, answer questions, fix tests, etc. and removed needs triage labels Aug 9, 2021
@ha-D ha-D force-pushed the hadi/se-4650/oep-15 branch from 859a51f to 7d8e6e6 Compare August 11, 2021 07:38
@ha-D
Copy link
Contributor Author

ha-D commented Aug 11, 2021

Thanks for the review @nizarmah.

I realized something was missing here while submitting the frontend PR. We also need to add the fields in the course_home_api django-app since this is the API that all non-courseware pages in the frontend will be using (rather than courseware_api).
This is added in the second commit, could you take a look at this as well.

Copy link
Contributor

@nizarmah nizarmah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ha-D nice work on the changes 👍🏼 I still have one minor comment I'll need you to address though, please. Sorry about that!

lms/templates/main.html Outdated Show resolved Hide resolved
@ha-D ha-D force-pushed the hadi/se-4650/oep-15 branch from 7d8e6e6 to cc8bdc6 Compare August 12, 2021 09:14
Copy link
Contributor

@nizarmah nizarmah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ha-D for addressing the final comment I had 👍🏼!

LGTM. I'll pass the review over to @bradenmacdonald.

@bradenmacdonald
Copy link
Contributor

@Colin-Fredericks I thought I should bring this PR to your attention :)

@bradenmacdonald
Copy link
Contributor

Also @msegado as the author of the original OEP, would you like to comment on this PR? Has there been any other implementation that we weren't aware of, btw?

Copy link
Contributor

@bradenmacdonald bradenmacdonald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@natabene I think this is ready for review now. Is this one I can take, or do you know who else might want to look at it?

@ha-D the code looks great to me, just saw one thing that needs to be bumped and had one question. Thanks for this nice work.

openedx/core/djangoapps/content/course_overviews/models.py Outdated Show resolved Hide resolved
openedx/core/djangoapps/courseware_api/serializers.py Outdated Show resolved Hide resolved
@Colin-Fredericks
Copy link
Contributor

@Colin-Fredericks I thought I should bring this PR to your attention :)

Yes! Thank you so much for putting this together. This will make deploying our existing javascript much faster and more effective, and it gets us access to pages we've never been able to deploy to before. Very much appreciated.

@ha-D ha-D force-pushed the hadi/se-4650/oep-15 branch from a09b23b to 1a25d7b Compare August 19, 2021 15:22
@msegado
Copy link
Contributor

msegado commented Aug 25, 2021

Also @msegado as the author of the original OEP, would you like to comment on this PR? Has there been any other implementation that we weren't aware of, btw?

Apologies for being late to the party! I'm not aware of any other implementations, so thanks to @ha-D for putting this one together; I expect the Harvard folks in particular will find it quite helpful. I also like the name change from "global" to "course-wide" - definitely clearer that way.

The only thing I'd suggest adding (eventually, doesn't need to be in this PR) is some text clarifying the security implications and support expectations for this feature. The OEP contains some sample wording that could work in the What about security? and What about compatibility and support? sections.

@ha-D ha-D force-pushed the hadi/se-4650/oep-15 branch from 1a25d7b to 0578e1c Compare August 27, 2021 11:41
@natabene
Copy link
Contributor

@bradenmacdonald Thanks for asking, let me check and get back to you asap.

@natabene
Copy link
Contributor

@bradenmacdonald Yes, that is fine, thank you!

@bradenmacdonald
Copy link
Contributor

@gabor-boros I just tested this now on the sandbox, and have only one concern:

Right now, this is a little bit inconsistent because of the partial roll-out of MFEs in courseware.

I can see the toast on the old Course outline page but not the new course outline page.

I can see the toast on the courseware page within the iframe as expected

I see the toast on the Discussion, Wiki, and Instructor tabs, but not on the Progress or Dates tabs (since those are MFEs).

Is it possible to make a quick fix to this so that the scripts only appear on the courseware pages (old or new), but not on the various other tabs? Because we've already heard that the MFEs will not allow these kind of script injections, so we know that eventually it won't be on any tabs at all other than courseware, and the current mixed situation could be confusing for course authors.

Otherwise this looks good and I'm ready to approve it.

@gabor-boros
Copy link
Contributor

Thank you @bradenmacdonald for reviewing this!
I'll check what I can do here. In the meantime, I rebased this PR on the master branch to make sure everything is up to date.

Imlements OEP-15 by adding two fields to the course settings:
- Course-wide Custom JS
- Course-wide Custom CSS
The resources defined in these fields will be rendered in all course pages.

Rebase b6cb629..0578e1c4c6 onto b6cb629:
- Add course-wide resources to API for MFE use
- Revert "Add course-wide resources to API for MFE use" reverts commit 53648dcf0afe3cd171c9dc2eb5e56b871b2bcfb2

Signed-off-by: Gabor Boros <gabor.brs@gmail.com>
@openedx-webhooks openedx-webhooks removed the waiting on author PR author needs to resolve review requests, answer questions, fix tests, etc. label Oct 4, 2021
@gabor-boros
Copy link
Contributor

gabor-boros commented Oct 4, 2021

@bradenmacdonald The only reasonable way I found is to render the assets if we are rendering courseware or an xBlock. Please let me know if this is not what you had in mind. The sandbox is on its way.

@edx-status-bot
Copy link

Your PR has finished running tests. The following contexts failed:

  • jenkins/django-3.2/python

@gabor-boros
Copy link
Contributor

@bradenmacdonald I'm not entirely sure about the issue on the CI, but the PR is ready for your review. If you would like to see it working with non-MFE, please check this PR.

Copy link
Contributor

@bradenmacdonald bradenmacdonald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for those changes, I think this is good to go now! Just have to ask about if the django3.2 test is a blocker for merge.

👍

  • I tested this: MFE and legacy experiences on the sandbox
  • I read through the code
  • I checked for accessibility issues: n/a
  • Includes documentation: some inline docs

@bradenmacdonald bradenmacdonald merged commit d3bc460 into openedx:master Oct 4, 2021
@openedx-webhooks
Copy link

@ha-D 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future.

@bradenmacdonald bradenmacdonald deleted the hadi/se-4650/oep-15 branch October 4, 2021 18:24
@edx-pipeline-bot
Copy link
Contributor

EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production.

@edx-pipeline-bot
Copy link
Contributor

EdX Release Notice: This PR may have caused e2e tests to fail on Stage. If you're a member of the edX org, please visit #e2e-troubleshooting on Slack to help diagnose the cause of these failures. Otherwise, it is the reviewer's responsibility. E2E tests have failed. https://gocd.tools.edx.org/go/tab/pipeline/history/deploy_to_stage

@edx-pipeline-bot
Copy link
Contributor

EdX Release Notice: This PR has been deployed to the production environment.

@alfredchavez
Copy link
Contributor

alfredchavez commented Oct 26, 2021

Hi @gabor-boros could you port this changes to lilac.master(if it's ok to do so)? as part of BB-4877
CC: @arbrandes for review

@kevincanavan
Copy link

@ha-D @bradenmacdonald - edX Partner Support has received a request for documentation on this feature. I've seen the original proposal doc, but since that hadn't been updated in years before this was merged, I'm not sure how much might have changed. Any help you can provide would be appreciated.

Specific questions (though anything additional is also welcomed):

  • proper syntax for adding both JS and CSS files/resources in their respective advanced settings fields
  • Where on the platform do these scripts/styles apply? Just inside the content iframe? On the items outside the frame? On custom pages? Presumably not in discussion forums.
  • Are there any specific things we should avoid – for instance, is there a built-in .invisible class that shouldn’t be overridden, or a javascript function named main() that shouldn’t be redefined?

Thanks in advance for any help you can offer.

@bradenmacdonald
Copy link
Contributor

@kevincanavan I'm about to take some time off, so I'll find someone else to answer your question. If not, I'll figure it out for you when I'm back. CC @gabor-boros

@xitij2000
Copy link
Contributor

@ha-D @bradenmacdonald - edX Partner Support has received a request for documentation on this feature. I've seen the original proposal doc, but since that hadn't been updated in years before this was merged, I'm not sure how much might have changed. Any help you can provide would be appreciated.

Specific questions (though anything additional is also welcomed):

* proper syntax for adding both JS and CSS files/resources in their respective advanced settings fields

* Where on the platform do these scripts/styles apply? Just inside the content iframe? On the items outside the frame? On custom pages? Presumably not in discussion forums.

* Are there any specific things we should avoid – for instance, is there a built-in .invisible class that shouldn’t be overridden, or a javascript function named main() that shouldn’t be redefined?

Thanks in advance for any help you can offer.

I've created a PR to update the OEP to match the current implementation: openedx/open-edx-proposals#396

I'm not sure if that's the right approach, if so, do tell me how/where I should document this.

  • These will only apply inside the content iframe.
  • I think making such an exhaustive list would be difficult, a lot of things to break the UI, so it might be better to just advise general caution. I don't know if there is any such advice when adding custom JS/CSS using raw HTML. If so we can duplicate that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged open-source-contribution PR author is not from Axim or 2U
Projects
None yet
Development

Successfully merging this pull request may close these issues.