feat: adds Library Content (v2) button to Studio Unit page (#35670)
Requires that v2 libraries are enabled.
This commit is contained in:
68
cms/static/js/views/components/add_library_content.js
Normal file
68
cms/static/js/views/components/add_library_content.js
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Provides utilities to open and close the library content picker.
|
||||
*
|
||||
*/
|
||||
define(['jquery', 'underscore', 'gettext', 'js/views/modals/base_modal'],
|
||||
function($, _, gettext, BaseModal) {
|
||||
'use strict';
|
||||
|
||||
var AddLibraryContent = BaseModal.extend({
|
||||
options: $.extend({}, BaseModal.prototype.options, {
|
||||
modalName: 'add-component-from-library',
|
||||
modalSize: 'lg',
|
||||
view: 'studio_view',
|
||||
viewSpecificClasses: 'modal-add-component-picker confirm',
|
||||
// Translators: "title" is the name of the current component being edited.
|
||||
titleFormat: gettext('Add library content'),
|
||||
addPrimaryActionButton: false,
|
||||
}),
|
||||
|
||||
initialize: function() {
|
||||
BaseModal.prototype.initialize.call(this);
|
||||
// Add event listen to close picker when the iframe tells us to
|
||||
const handleMessage = (event) => {
|
||||
if (event.data?.type === 'pickerComponentSelected') {
|
||||
var requestData = {
|
||||
library_content_key: event.data.usageKey,
|
||||
category: event.data.category,
|
||||
}
|
||||
this.refreshFunction(requestData);
|
||||
this.hide();
|
||||
}
|
||||
};
|
||||
this.messageListener = window.addEventListener("message", handleMessage);
|
||||
this.cleanupListener = () => { window.removeEventListener("message", handleMessage) };
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
BaseModal.prototype.hide.call(this);
|
||||
this.cleanupListener();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the action buttons to the modal.
|
||||
*/
|
||||
addActionButtons: function() {
|
||||
this.addActionButton('cancel', gettext('Cancel'));
|
||||
},
|
||||
|
||||
/**
|
||||
* Show a component picker modal from library.
|
||||
* @param contentPickerUrl Url for component picker
|
||||
* @param refreshFunction A function to refresh the block after it has been updated
|
||||
*/
|
||||
showComponentPicker: function(contentPickerUrl, refreshFunction) {
|
||||
this.contentPickerUrl = contentPickerUrl;
|
||||
this.refreshFunction = refreshFunction;
|
||||
|
||||
this.render();
|
||||
this.show();
|
||||
},
|
||||
|
||||
getContentHtml: function() {
|
||||
return `<iframe src="${this.contentPickerUrl}" onload="this.contentWindow.focus()" frameborder="0" style="width: 100%; height: 100%;"/>`;
|
||||
},
|
||||
});
|
||||
|
||||
return AddLibraryContent;
|
||||
});
|
||||
@@ -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({
|
||||
@@ -67,14 +68,32 @@ 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') {
|
||||
var modal = new AddLibraryContent();
|
||||
modal.showComponentPicker(
|
||||
this.options.libraryContentPickerUrl,
|
||||
function(data) {
|
||||
ViewUtils.runOperationShowingMessage(
|
||||
gettext('Adding'),
|
||||
_.bind(this.options.createComponent, this, data, $element),
|
||||
).always(function() {
|
||||
// Restore the scroll position of the buttons so that the new
|
||||
// component appears above them.
|
||||
ViewUtils.setScrollOffset(self.$el, oldOffset);
|
||||
});
|
||||
}.bind(this)
|
||||
);
|
||||
} 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -214,7 +214,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();
|
||||
});
|
||||
@@ -224,7 +225,7 @@ function($, _, Backbone, gettext, BasePage,
|
||||
},
|
||||
|
||||
initializePasteButton() {
|
||||
if (this.options.canEdit && !self.options.isIframeEmbed) {
|
||||
if (this.options.canEdit && !this.options.isIframeEmbed) {
|
||||
// We should have the user's clipboard status.
|
||||
const data = this.options.clipboardData;
|
||||
this.refreshPasteButton(data);
|
||||
@@ -241,7 +242,7 @@ function($, _, Backbone, gettext, BasePage,
|
||||
refreshPasteButton(data) {
|
||||
// Do not perform any changes on paste button since they are not
|
||||
// rendered on Library or LibraryContent pages
|
||||
if (!this.isLibraryPage && !this.isLibraryContentPage && !self.options.isIframeEmbed) {
|
||||
if (!this.isLibraryPage && !this.isLibraryContentPage && !this.options.isIframeEmbed) {
|
||||
// 'data' is the same data returned by the "get clipboard status" API endpoint
|
||||
// i.e. /api/content-staging/v1/clipboard/
|
||||
if (this.options.canEdit && data.content) {
|
||||
|
||||
Reference in New Issue
Block a user