From d5c5b00a6fe32d6b809117f56ce25dee080deb53 Mon Sep 17 00:00:00 2001 From: Jillian Vogel Date: Tue, 18 Feb 2025 13:30:38 +1030 Subject: [PATCH 1/3] fix: allow LTI blocks to be loaded in a Library v2 context --- xmodule/lti_block.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/xmodule/lti_block.py b/xmodule/lti_block.py index 944a7ec88db0..f4503dcf232d 100644 --- a/xmodule/lti_block.py +++ b/xmodule/lti_block.py @@ -68,6 +68,7 @@ from django.conf import settings from lxml import etree from oauthlib.oauth1.rfc5849 import signature +from opaque_keys.edx.keys import CourseKey from pytz import UTC from web_fragments.fragment import Fragment from webob import Response @@ -609,8 +610,12 @@ def get_lis_result_sourcedid(self): def get_course(self): """ Return course by course id. + + Returns None if the current block is not part of a course (i.e part of a library). """ - return self.runtime.modulestore.get_course(self.course_id) + if isinstance(self.course_id, CourseKey): + return self.runtime.modulestore.get_course(self.course_id) + return None @property def context_id(self): @@ -960,7 +965,8 @@ def get_client_key_secret(self): Obtains client_key and client_secret credentials from current course. """ course = self.get_course() - for lti_passport in course.lti_passports: + lti_passports = course.lti_passports if course else [] + for lti_passport in lti_passports: try: lti_id, key, secret = [i.strip() for i in lti_passport.split(':')] except ValueError: From ad4281251ab5ec4e99a014672d4801e1a7c05754 Mon Sep 17 00:00:00 2001 From: Jillian Vogel Date: Tue, 18 Feb 2025 16:32:44 +1030 Subject: [PATCH 2/3] fix: use 400px as min-width for iframed xblocks so that they fit better in the preview sidebar and expanded iframe views --- cms/static/sass/course-unit-mfe-iframe-bundle.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/static/sass/course-unit-mfe-iframe-bundle.scss b/cms/static/sass/course-unit-mfe-iframe-bundle.scss index c9b111b91283..df235e177dc5 100644 --- a/cms/static/sass/course-unit-mfe-iframe-bundle.scss +++ b/cms/static/sass/course-unit-mfe-iframe-bundle.scss @@ -2,7 +2,7 @@ @import 'elements/course-unit-mfe-iframe'; body { - min-width: 800px; + min-width: 400px; } .wrapper { From 57ce36cadf638ba20623a7388ccc1dab0735e492 Mon Sep 17 00:00:00 2001 From: Jillian Vogel Date: Wed, 19 Feb 2025 16:57:56 +1030 Subject: [PATCH 3/3] refactor: move studio_submit to EditingMixin and generalize it so it can be used by LTI and WordCloud blocks --- xmodule/editing_block.py | 19 ++++++++++++++++++- xmodule/word_cloud_block.py | 20 -------------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/xmodule/editing_block.py b/xmodule/editing_block.py index c35dc57bf652..13f42f5fdd07 100644 --- a/xmodule/editing_block.py +++ b/xmodule/editing_block.py @@ -3,7 +3,8 @@ import logging -from xblock.fields import Scope, String +from xblock.core import XBlock +from xblock.fields import Boolean, Scope, String from xmodule.mako_block import MakoTemplateBlockBase @@ -43,3 +44,19 @@ def get_context(self): # Add our specific template information (the raw data body) _context.update({'data': self.data}) return _context + + @XBlock.json_handler + def studio_submit(self, submissions, suffix=''): # pylint: disable=unused-argument + """ + Change the settings for this XBlock given by the Studio user + """ + for field_name in self.editable_metadata_fields: + if field_name in submissions and field_name in self.fields: + field = self.fields[field_name] + if isinstance(field, Boolean): + setattr(self, field_name, submissions[field_name] == 'True') + else: + setattr(self, field_name, submissions[field_name]) + return { + 'result': 'success', + } diff --git a/xmodule/word_cloud_block.py b/xmodule/word_cloud_block.py index f83cda8c0c83..37e82400df78 100644 --- a/xmodule/word_cloud_block.py +++ b/xmodule/word_cloud_block.py @@ -315,26 +315,6 @@ def index_dictionary(self): return xblock_body - @XBlock.json_handler - def studio_submit(self, submissions, suffix=''): # pylint: disable=unused-argument - """ - Change the settings for this XBlock given by the Studio user - """ - if 'display_name' in submissions: - self.display_name = submissions['display_name'] - if 'instructions' in submissions: - self.instructions = submissions['instructions'] - if 'num_inputs' in submissions: - self.num_inputs = submissions['num_inputs'] - if 'num_top_words' in submissions: - self.num_top_words = submissions['num_top_words'] - if 'display_student_percents' in submissions: - self.display_student_percents = submissions['display_student_percents'] == 'True' - - return { - 'result': 'success', - } - WordCloudBlock = ( _ExtractedWordCloudBlock if settings.USE_EXTRACTED_WORD_CLOUD_BLOCK