Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: fix lint warnings in course_outline.js
Browse files Browse the repository at this point in the history
bradenmacdonald committed Jan 27, 2025
1 parent 0659a6a commit 2d8f5fd
Showing 1 changed file with 79 additions and 88 deletions.
167 changes: 79 additions & 88 deletions cms/static/js/views/course_outline.js
Original file line number Diff line number Diff line change
@@ -237,46 +237,44 @@ function(

/** Copy a Unit to the clipboard */
copyXBlock() {
const clipboardEndpoint = "/api/content-staging/v1/clipboard/";
const clipboardEndpoint = '/api/content-staging/v1/clipboard/';
// Start showing a "Copying" notification:
ViewUtils.runOperationShowingMessage(gettext('Copying'), () => {
return $.postJSON(
clipboardEndpoint,
{ usage_key: this.model.get('id') }
).then((data) => {
// const status = data.content?.status;
const status = data.content && data.content.status;
// ^ platform's old require.js/esprima breaks on newer syntax in some JS files but not all.
if (status === "ready") {
// The Unit has been copied and is ready to use.
this.clipboardManager.updateUserClipboard(data); // This will update the UI and notify other tabs
return data;
} else if (status === "loading") {
// The clipboard is being loaded asynchronously.
// Poll the endpoint until the copying process is complete:
const deferred = $.Deferred();
const checkStatus = () => {
$.getJSON(clipboardEndpoint, (pollData) => {
// const newStatus = pollData.content?.status;
const newStatus = pollData.content && pollData.content.status;
if (newStatus === "ready") {
this.clipboardManager.updateUserClipboard(pollData);
deferred.resolve(pollData);
} else if (newStatus === "loading") {
setTimeout(checkStatus, 1000);
} else {
deferred.reject();
throw new Error(`Unexpected clipboard status "${newStatus}" in successful API response.`);
}
})
}
setTimeout(checkStatus, 1000);
return deferred;
} else {
throw new Error(`Unexpected clipboard status "${status}" in successful API response.`);
}
});
});
ViewUtils.runOperationShowingMessage(gettext('Copying'), () => $.postJSON(
clipboardEndpoint,
{usage_key: this.model.get('id')}
).then((data) => {
// const status = data.content?.status;
const status = data.content && data.content.status;
// ^ platform's old require.js/esprima breaks on newer syntax in some JS files but not all.
if (status === 'ready') {
// The Unit has been copied and is ready to use.
this.clipboardManager.updateUserClipboard(data); // This will update the UI and notify other tabs
return data;
} else if (status === 'loading') {
// The clipboard is being loaded asynchronously.
// Poll the endpoint until the copying process is complete:
const deferred = $.Deferred();
const checkStatus = () => {
$.getJSON(clipboardEndpoint, (pollData) => {
// const newStatus = pollData.content?.status;
const newStatus = pollData.content && pollData.content.status;
if (newStatus === 'ready') {
this.clipboardManager.updateUserClipboard(pollData);
deferred.resolve(pollData);
} else if (newStatus === 'loading') {
setTimeout(checkStatus, 1000);
} else {
deferred.reject();
throw new Error(`Unexpected clipboard status "${newStatus}" in successful API response.`);
}
});
};
setTimeout(checkStatus, 1000);
return deferred;
} else {
throw new Error(`Unexpected clipboard status "${status}" in successful API response.`);
}
}));
},

initializePasteButton(element) {
@@ -285,11 +283,11 @@ function(
// We should have the user's clipboard status from CourseOutlinePage, whose clipboardManager manages
// the clipboard data on behalf of all the XBlocks in the outline.
this.refreshPasteButton(this.clipboardManager.userClipboard);
this.clipboardManager.addEventListener("update", (event) => {
this.clipboardManager.addEventListener('update', (event) => {
this.refreshPasteButton(event.detail);
});
} else {
this.$(".paste-component").hide();
this.$('.paste-component').hide();
}
}
},
@@ -301,41 +299,38 @@ function(
// '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) {
if (data.content.status === "expired") {
if (data.content.status === 'expired') {
// This has expired and can no longer be pasted.
this.$(".paste-component").hide();
this.$('.paste-component').hide();
} else if (data.content.block_type === 'vertical') {
// This is suitable for pasting as a unit.
const detailsPopupEl = this.$(".clipboard-details-popup")[0];
const detailsPopupEl = this.$('.clipboard-details-popup')[0];
// Only Units should have the paste button initialized
if (detailsPopupEl !== undefined) {
const detailsPopupEl = this.$(".clipboard-details-popup")[0];
detailsPopupEl.querySelector(".detail-block-name").innerText = data.content.display_name;
detailsPopupEl.querySelector(".detail-block-type").innerText = data.content.block_type_display;
detailsPopupEl.querySelector(".detail-course-name").innerText = data.source_context_title;
detailsPopupEl.querySelector('.detail-block-name').innerText = data.content.display_name;
detailsPopupEl.querySelector('.detail-block-type').innerText = data.content.block_type_display;
detailsPopupEl.querySelector('.detail-course-name').innerText = data.source_context_title;
if (data.source_edit_url) {
detailsPopupEl.setAttribute("href", data.source_edit_url);
detailsPopupEl.classList.remove("no-edit-link");
detailsPopupEl.setAttribute('href', data.source_edit_url);
detailsPopupEl.classList.remove('no-edit-link');
} else {
detailsPopupEl.setAttribute("href", "#");
detailsPopupEl.classList.add("no-edit-link");
detailsPopupEl.setAttribute('href', '#');
detailsPopupEl.classList.add('no-edit-link');
}
this.$('.paste-component').show()
this.$('.paste-component').show();
}

} else {
this.$('.paste-component').hide()
this.$('.paste-component').hide();
}

} else {
this.$('.paste-component').hide();
}
},

createPlaceholderElementForPaste(category, componentDisplayName) {
const nameStr = StringUtils.interpolate(gettext("Copy of '{componentDisplayName}'"), { componentDisplayName }, true);
const el = document.createElement("li");
el.classList.add("outline-item", "outline-" + category, "has-warnings", "is-draggable");
const nameStr = StringUtils.interpolate(gettext('Copy of "{componentDisplayName}"'), {componentDisplayName}, true);
const el = document.createElement('li');
el.classList.add('outline-item', 'outline-' + category, 'has-warnings', 'is-draggable');
el.innerHTML = `
<div class="${category}-header">
<h3 class="${category}-header-details" style="width: 50%">
@@ -369,17 +364,15 @@ function(
$listPanel.append($placeholderEl);

// Start showing a "Pasting" notification:
ViewUtils.runOperationShowingMessage(gettext('Pasting'), () => {
return $.postJSON(this.model.urlRoot + '/', {
parent_locator: parentLocator,
staged_content: "clipboard",
}).then((data) => {
this.refresh(); // Update this and replace the placeholder with the actual pasted unit.
return data;
}).fail(() => {
$placeholderEl.remove();
});
}).done((data) => {
ViewUtils.runOperationShowingMessage(gettext('Pasting'), () => $.postJSON(this.model.urlRoot + '/', {
parent_locator: parentLocator,
staged_content: 'clipboard',
}).then((data) => {
this.refresh(); // Update this and replace the placeholder with the actual pasted unit.
return data;
}).fail(() => {
$placeholderEl.remove();
})).done((data) => {
const {
conflicting_files: conflictingFiles,
error_files: errorFiles,
@@ -389,32 +382,32 @@ function(
const notices = [];
if (errorFiles.length) {
notices.push((next) => new PromptView.Error({
title: gettext("Some errors occurred"),
title: gettext('Some errors occurred'),
message: (
gettext("The following required files could not be added to the course:") +
" " + errorFiles.join(", ")
gettext('The following required files could not be added to the course:')
+ ' ' + errorFiles.join(', ')
),
actions: {primary: {text: gettext("OK"), click: (x) => { x.hide(); next(); }}},
actions: {primary: {text: gettext('OK'), click: (x) => { x.hide(); next(); }}},
}));
}
if (conflictingFiles.length) {
notices.push((next) => new PromptView.Warning({
title: gettext("You may need to update a file(s) manually"),
title: gettext('You may need to update a file(s) manually'),
message: (
gettext(
"The following files already exist in this course but don't match the " +
"version used by the component you pasted:"
) + " " + conflictingFiles.join(", ")
'The following files already exist in this course but don\'t match the '
+ 'version used by the component you pasted:'
) + ' ' + conflictingFiles.join(', ')
),
actions: {primary: {text: gettext("OK"), click: (x) => { x.hide(); next(); }}},
actions: {primary: {text: gettext('OK'), click: (x) => { x.hide(); next(); }}},
}));
}
if (newFiles.length) {
notices.push(() => new NotificationView.Info({
title: gettext("New file(s) added to Files & Uploads."),
title: gettext('New file(s) added to Files & Uploads.'),
message: (
gettext("The following required files were imported to this course:") +
" " + newFiles.join(", ")
gettext('The following required files were imported to this course:')
+ ' ' + newFiles.join(', ')
),
actions: {
primary: {
@@ -423,7 +416,6 @@ function(
const article = document.querySelector('[data-course-assets]');
const assetsUrl = $(article).attr('data-course-assets');
window.location.href = assetsUrl;
return;
}
},
secondary: {
@@ -440,7 +432,7 @@ function(
const showNext = () => {
const view = notices.shift()(showNext);
view.show();
}
};
// Delay to avoid conflict with the "Pasting..." notification.
setTimeout(showNext, 1250);
}
@@ -478,14 +470,13 @@ function(
* If the new "Actions" menu is enabled, most actions like Configure,
* Duplicate, Move, Delete, etc. are moved into this menu. For this
* event, we just toggle displaying the menu.
* @param {*} event
*/
showActionsMenu(event) {
const showActionsButton = event.currentTarget;
const subMenu = showActionsButton.parentElement.querySelector(".wrapper-nav-sub");
const subMenu = showActionsButton.parentElement.querySelector('.wrapper-nav-sub');

// Close all open dropdowns
const elements = document.querySelectorAll("li.action-item.action-actions-menu.nav-item");
const elements = document.querySelectorAll('li.action-item.action-actions-menu.nav-item');
elements.forEach(element => {
if (element !== showActionsButton.parentElement) {
element.querySelector('.wrapper-nav-sub').classList.remove('is-shown');
@@ -494,7 +485,7 @@ function(

// Code in 'base.js' normally handles toggling these dropdowns but since this one is
// not present yet during the domReady event, we have to handle displaying it ourselves.
subMenu.classList.toggle("is-shown");
subMenu.classList.toggle('is-shown');
// if propagation is not stopped, the event will bubble up to the
// body element, which will close the dropdown.
event.stopPropagation();

0 comments on commit 2d8f5fd

Please sign in to comment.