Skip to content

Commit

Permalink
feat: adds Library Content button
Browse files Browse the repository at this point in the history
iframes the Authoring MFE's Library Content Picker
  • Loading branch information
pomegranited committed Oct 16, 2024
1 parent 2cb69c0 commit df77ff7
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 14 deletions.
2 changes: 2 additions & 0 deletions cms/djangoapps/contentstore/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ def xblock_type_display_name(xblock, default_display_name=None):
# description like "Multiple Choice Problem", but that won't work if our 'block' argument is just the block_type
# string ("problem").
return _('Problem')
elif category == 'library_v2':
return _('Library Content')
component_class = XBlock.load_class(category)
if hasattr(component_class, 'display_name') and component_class.display_name.default:
return _(component_class.display_name.default) # lint-amnesty, pylint: disable=translation-of-non-string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class ContainerHandlerSerializer(serializers.Serializer):
unit_block_id = serializers.CharField(source="unit.location.block_id")
subsection_location = serializers.CharField(source="subsection.location")
course_sequence_ids = serializers.ListField(child=serializers.CharField())
library_content_picker_url = serializers.CharField()

def get_assets_url(self, obj):
"""
Expand Down
12 changes: 12 additions & 0 deletions cms/djangoapps/contentstore/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,17 @@ def get_course_outline_url(course_locator) -> str:
return course_outline_url


def get_library_content_picker_url(block_locator) -> str:
"""
Gets course authoring microfrontend library content picker URL for the given parent block.
"""
course_locator = block_locator.course_key
mfe_base_url = get_course_authoring_url(course_locator)
content_picker_url = f'{mfe_base_url}/component-picker?parentLocator={block_locator}'

return content_picker_url


def get_unit_url(course_locator, unit_locator) -> str:
"""
Gets course authoring microfrontend URL for unit page view.
Expand Down Expand Up @@ -2046,6 +2057,7 @@ def get_container_handler_context(request, usage_key, course, xblock): # pylint
'user_clipboard': user_clipboard,
'is_fullwidth_content': is_library_xblock,
'course_sequence_ids': course_sequence_ids,
'library_content_picker_url': get_library_content_picker_url(xblock.location),
}
return context

Expand Down
16 changes: 15 additions & 1 deletion cms/djangoapps/contentstore/views/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,16 @@
log = logging.getLogger(__name__)

# NOTE: This list is disjoint from ADVANCED_COMPONENT_TYPES
COMPONENT_TYPES = ['discussion', 'library', 'html', 'openassessment', 'problem', 'video', 'drag-and-drop-v2']
COMPONENT_TYPES = [
'discussion',
'library',
'library_v2',
'html',
'openassessment',
'problem',
'video',
'drag-and-drop-v2',
]

ADVANCED_COMPONENT_TYPES = sorted({name for name, class_ in XBlock.load_classes()} - set(COMPONENT_TYPES))

Expand Down Expand Up @@ -95,6 +104,10 @@ def _load_mixed_class(category):
"""
Load an XBlock by category name, and apply all defined mixins
"""
# Libraries v2 content doesn't have an XBlock.
if category == 'library_v2':
return None

component_class = XBlock.load_class(category)
mixologist = Mixologist(settings.XBLOCK_MIXINS)
return mixologist.mix(component_class)
Expand Down Expand Up @@ -216,6 +229,7 @@ def create_support_legend_dict():
'video': _("Video"),
'openassessment': _("Open Response"),
'library': _("Legacy Library"),
'library_v2': _("Library Content"),
'drag-and-drop-v2': _("Drag and Drop"),
}

Expand Down
Binary file added cms/static/images/large-library_v2-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions cms/static/js/views/components/add_library_content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Provides utilities to open and close the library content picker.
*
* To use this picker you need to add the following code into your template:
*
* ```
* <div id="library-content-picker" class="picker"></div>
* <div class="picker-cover"></div>
* ```
*/
define(['jquery'],
function($) {
'use strict';

const closePicker = (picker, pickerCover) => {
$(pickerCover).css('display', 'none');
$(picker).empty();
$(picker).css('display', 'none');
$('body').removeClass('picker-open');
};

const openPicker = (contentPickerUrl, picker, pickerCover) => {
// Add event listen to close picker when the iframe tells us to
window.addEventListener("message", function (event) {
if (event.data === 'closeComponentPicker') {
closePicker(picker, pickerCover);
}
}.bind(this));

$(pickerCover).css('display', 'block');
// xss-lint: disable=javascript-jquery-html
$(picker).html(
`<iframe src="${contentPickerUrl}" onload="this.contentWindow.focus()" frameborder="0" style="width: 100%; height: 100%;"></iframe>`
);
$(picker).css('display', 'block');

// Prevent background from being scrollable when picker is open
$('body').addClass('picker-open');
};

const createComponent = (contentPickerUrl) => {
const picker = document.querySelector("#library-content-picker");
const pickerCover = document.querySelector(".picker-cover");

return openPicker(contentPickerUrl, picker, pickerCover);
};

return {
createComponent: createComponent,
};
});
24 changes: 15 additions & 9 deletions cms/static/js/views/components/add_xblock.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
*/
define(['jquery', 'underscore', 'gettext', 'js/views/baseview', 'common/js/components/utils/view_utils',
'js/views/components/add_xblock_button', 'js/views/components/add_xblock_menu',
'js/views/components/add_library_content',
'edx-ui-toolkit/js/utils/html-utils'],
function($, _, gettext, BaseView, ViewUtils, AddXBlockButton, AddXBlockMenu, HtmlUtils) {
function($, _, gettext, BaseView, ViewUtils, AddXBlockButton, AddXBlockMenu, AddLibraryContent, HtmlUtils) {
'use strict';

var AddXBlockComponent = BaseView.extend({
Expand Down Expand Up @@ -67,14 +68,19 @@ function($, _, gettext, BaseView, ViewUtils, AddXBlockButton, AddXBlockMenu, Htm
oldOffset = ViewUtils.getScrollOffset(this.$el);
event.preventDefault();
this.closeNewComponent(event);
ViewUtils.runOperationShowingMessage(
gettext('Adding'),
_.bind(this.options.createComponent, this, saveData, $element)
).always(function() {
// Restore the scroll position of the buttons so that the new
// component appears above them.
ViewUtils.setScrollOffset(self.$el, oldOffset);
});

if (saveData.type === 'library_v2') {
AddLibraryContent.createComponent(this.options.libraryContentPickerUrl);
} else {
ViewUtils.runOperationShowingMessage(
gettext('Adding'),
_.bind(this.options.createComponent, this, saveData, $element),
).always(function() {
// Restore the scroll position of the buttons so that the new
// component appears above them.
ViewUtils.setScrollOffset(self.$el, oldOffset);
});
}
}
});

Expand Down
3 changes: 2 additions & 1 deletion cms/static/js/views/pages/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ function($, _, Backbone, gettext, BasePage,
var component = new AddXBlockComponent({
el: element,
createComponent: _.bind(self.createComponent, self),
collection: self.options.templates
collection: self.options.templates,
libraryContentPickerUrl: self.options.libraryContentPickerUrl,
});
component.render();
});
Expand Down
7 changes: 7 additions & 0 deletions cms/static/sass/assets/_graphics.scss
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,10 @@
height: ($baseline*3);
background: url('#{$static-path}/images/large-library-icon.png') center no-repeat;
}

.large-library_v2-icon {
display: inline-block;
width: ($baseline*3);
height: ($baseline*3);
background: url('#{$static-path}/images/large-library_v2-icon.png') center no-repeat;
}
22 changes: 19 additions & 3 deletions cms/static/sass/elements/_drawer.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// studio - elements - side drawers
// ====================

.drawer-cover {
.drawer-cover,
.picker-cover {
@extend %ui-depth3;

display: none;
Expand All @@ -13,7 +14,8 @@
background: rgba(0, 0, 0, 0.8);
}

.drawer-cover.gray-cover {
.drawer-cover.gray-cover,
.picker-cover.gray-cover {
background: rgba(112, 112, 112, 0.8);
}

Expand All @@ -29,6 +31,20 @@
background-color: $gray-l4;
}

body.drawer-open {
body.drawer-open,
body.picker-open {
overflow: hidden;
}

.picker {
@extend %ui-depth4;

display: none;
position: fixed;
top: 1em;
left: 1em;
right: 1em;
bottom: 1em;
background-color: $gray-l4;
}

4 changes: 4 additions & 0 deletions cms/templates/container.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
isUnitPage: ${is_unit_page | n, dump_js_escaped_json},
canEdit: true,
outlineURL: "${outline_url | n, js_escaped_string}",
libraryContentPickerUrl: "${library_content_picker_url | n, js_escaped_string}",
clipboardData: ${user_clipboard | n, dump_js_escaped_json},
}
);
Expand Down Expand Up @@ -299,4 +300,7 @@ <h5 class="title">${_("Location ID")}</h5>

<div id="manage-tags-drawer" class="drawer"></div>
<div class="drawer-cover gray-cover"></div>

<div id="library-content-picker" class="picker"></div>
<div class="picker-cover gray-cover"></div>
</%block>

0 comments on commit df77ff7

Please sign in to comment.