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

[FC-0056][Plugin] Course outline sidebar (plugin wrapper) #1349

Conversation

ihor-romaniuk
Copy link
Contributor

@ihor-romaniuk ihor-romaniuk commented Apr 9, 2024

Settings

EDX_PLATFORM_REPOSITORY: https://github.com/raccoongang/edx-platform.git
EDX_PLATFORM_VERSION: ts-develop

Description

This pull request adds an important feature to our platform: displaying a navigation sidebar within a given course.

Interaction with feature flag courseware.show_default_right_sidebar has been added to control the default display of the discussion sidebar.

Discussions or Notifications sidebar shouldn't be opened on Learning MFE by default. If waffle flag enabled - Discussions always opens on the pages with discussions, if user is in Audit and course has verified mode - show Notifications.

Note: Initial solution without using Frontend Plugin Framework #1342

Depends on BE PRs

Design

https://www.figma.com/file/gew5tORDX4Q7wxOS8vjqZu/side-nav-OEX?type=design&node-id=318-3234&mode=design&t=rBe1ToNYP8RY6QOp-0

image

Testing instructions

  1. Run master devstack.
  2. Start platform make dev.up.lms+cms+frontend-app-course-authoring and make checkout on this branch.
  3. Go to Course Unit page from the Course Outline page.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Apr 9, 2024
@openedx-webhooks
Copy link

Thanks for the pull request, @ihor-romaniuk! 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.

This is currently a draft pull request. When it is ready for our review and all tests are green, click "Ready for Review", or remove "WIP" from the title, as appropriate.

@ihor-romaniuk ihor-romaniuk changed the title [FC-0056][Plugin] Course outline sidebar [FC-0056][Plugin] Course outline sidebar (plugin wrapper) Apr 9, 2024
@ihor-romaniuk ihor-romaniuk force-pushed the romaniuk/sidebar-main-plugin-wrapper branch from 86fedd4 to ddb94b0 Compare April 15, 2024 09:51
@itsjeyd itsjeyd added the product review PR requires product review before merging label Apr 22, 2024
Copy link

@arbrandes arbrandes 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 left some actual requests for changes, but mostly I'm just having a hard time understanding how sidebars are supposed to work... and that is not a good sign. So, would you mind doing the following?

  • Rebasing on master and squashing all commits into one, with a proper conventional commit message that describes any breaking changes (if there are any)
  • Removing the ENABLE_NEW_SIDEBAR environment variable so that the new one is the only one that exists; this includes removing all traces of the old sidebar
  • Making sure any PluginSlots introduced here don't require env.config.jsx to exist for the content they wrap to actually work
  • Making sure that the new sidebar is actually in a plugin slot

Let me know if there are reasons why any of the above don't make sense.

@@ -37,7 +40,7 @@ const Course = ({
const sequence = useModel('sequences', sequenceId);
const section = useModel('sections', sequence ? sequence.sectionId : null);
const enableNewSidebar = getConfig().ENABLE_NEW_SIDEBAR;

Choose a reason for hiding this comment

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

Can we get rid of this env var and just enable it by default?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if we should include refactoring the existing sidebars and removing the old one.
If we want to keep only the new sidebar, then we need to delete all links and files regarding the old sidebar, which can take a lot of time.

example.env.config.jsx Outdated Show resolved Hide resolved
<PluginSlot id={OUTLINE_SIDEBAR_DESKTOP_PLUGIN_SLOT_ID}>
<CourseOutlineTrigger isMobileView />
</PluginSlot>
{enableNewSidebar === 'true' ? <NewSidebarTriggers /> : <SidebarTriggers /> }

Choose a reason for hiding this comment

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

Again, it would be best if we just went with it and removed the old triggers.

Copy link
Contributor Author

@ihor-romaniuk ihor-romaniuk Apr 26, 2024

Choose a reason for hiding this comment

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

This all involves refactoring the new and old sidebars, which I wouldn't include in this PR.

];

return sidebarPluginSlots.every(
key => Object.prototype.hasOwnProperty.call(pluginSlots, key) && pluginSlots[key].keepDefault === true,

Choose a reason for hiding this comment

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

This is very nicely implemented (congrats), but the thing is, we want the sidebars to be enabled whether somebody has bothered to create an env.config.jsx or not.

In other words, the sidebar should just be on for everybody, except if they do something about it.

Copy link
Contributor Author

@ihor-romaniuk ihor-romaniuk Apr 26, 2024

Choose a reason for hiding this comment

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

In another case, we must check whether the Plugin slot that relates to the navigation sidebar is disabled.

Suggested change
key => Object.prototype.hasOwnProperty.call(pluginSlots, key) && pluginSlots[key].keepDefault === true,
key => (Object.prototype.hasOwnProperty.call(pluginSlots, key) ? pluginSlots[key].keepDefault !== false : true),

*/
export async function getCourseOutline(courseId) {
const { data } = await getAuthenticatedHttpClient()
.get(`${getConfig().LMS_BASE_URL}/api/course_home/v1/navigation/${courseId}`);

Choose a reason for hiding this comment

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

Does this mean this depends on openedx/edx-platform#34457? Can you please add this fact to the description of the PR?

Also, the PR sandbox settings is one of the additional ways to document this stuff. Please make it so the edx-platform branch points to that PR, instead of the raccoongang development branch.

Copy link
Member

@GlugovGrGlib GlugovGrGlib Apr 25, 2024

Choose a reason for hiding this comment

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

OK, this API call should be removed as this check is not required because of the wrapping sidebar into PluginSlot
UPD: I missread, this API call won't be removed, and is indeed related to openedx/edx-platform#34457, this will be added to description

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added the related BE PR to the "Depends on BE PRs" PR description block

@@ -43,6 +44,7 @@ describe('Data layer integration tests', () => {
const sequenceUrl = `${sequenceBaseUrl}/${sequenceMetadata.item_id}`;
const sequenceId = sequenceBlocks[0].id;
const unitId = unitBlocks[0].id;
const rightSidebarSettingsUrl = `${getConfig().LMS_BASE_URL}/courses/${courseId}/show-default-right-sidebar/enabled/`;

Choose a reason for hiding this comment

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

Where is this implemented in the backend? It's not in openedx/edx-platform#34457, as far as I can see. Or is it just a mock?

Copy link
Member

Choose a reason for hiding this comment

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

I believe the PR with waffle flag will be opened in the follow up PR, as we've got a recent refactoring of the flag, cause of product feedback - raccoongang/edx-platform#2514

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a draft note about relation to BE PR to the "Depends on BE PRs" PR description block and will be updated when PR will be open

const sequenceId = Object.keys(state.courseOutline.sequences)
.find(id => state.courseOutline.sequences[id].unitIds.includes(unitId));
const sequenceUnits = state.courseOutline.sequences[sequenceId].unitIds;
const isAllUnitsAreComplete = sequenceUnits.every((id) => state.courseOutline.units[id].complete);

Choose a reason for hiding this comment

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

Suggested change
const isAllUnitsAreComplete = sequenceUnits.every((id) => state.courseOutline.units[id].complete);
const areAllUnitsComplete = sequenceUnits.every((id) => state.courseOutline.units[id].complete);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course, thanks

const sectionId = Object.keys(state.courseOutline.sections)
.find(id => state.courseOutline.sections[id].sequenceIds.includes(sequenceId));
const sectionSequences = state.courseOutline.sections[sectionId].sequenceIds;
const isAllSequencesAreComplete = sectionSequences.every((id) => state.courseOutline.sequences[id].complete);

Choose a reason for hiding this comment

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

Suggested change
const isAllSequencesAreComplete = sectionSequences.every((id) => state.courseOutline.sequences[id].complete);
const areAllSequencesComplete = sectionSequences.every((id) => state.courseOutline.sequences[id].complete);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed, thanks

return null;
}

if (layout !== SIDEBARS[currentSidebar]?.LAYOUT) {

Choose a reason for hiding this comment

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

What are we protecting against, here? An MFE developer trying to insert a sidebar on the wrong side? But if each sidebar has a hard-coded side, then why let them specify the layout as a prop in the first place?

Copy link
Contributor Author

@ihor-romaniuk ihor-romaniuk Apr 26, 2024

Choose a reason for hiding this comment

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

In general, I would not remove this protection in case of further expansion and potential problems.

<PluginSlot id={OUTLINE_SIDEBAR_MOBILE_PLUGIN_SLOT_ID}>
<CourseOutlineTrigger />
</PluginSlot>
<Sidebar layout={LAYOUT_LEFT} />

Choose a reason for hiding this comment

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

If the sidebar is outside the PluginSlot, how will people be able to customize it?

@itsjeyd
Copy link

itsjeyd commented Apr 26, 2024

OSPR management note: This is part of a set of PRs for implementing Phase 1 changes for the FC-0056 project. We can consider it approved from the product perspective.

CC @GlugovGrGlib

@itsjeyd itsjeyd added the waiting on author PR author needs to resolve review requests, answer questions, fix tests, etc. label Apr 26, 2024
Copy link

codecov bot commented Apr 26, 2024

Codecov Report

Attention: Patch coverage is 95.58360% with 14 lines in your changes are missing coverage. Please review.

Project coverage is 88.60%. Comparing base (72381a7) to head (219ecb8).

Files Patch % Lines
...urseware/course/sidebar/SidebarContextProvider.jsx 80.00% 4 Missing ⚠️
...ebar/sidebars/course-outline/CourseOutlineTray.jsx 91.66% 4 Missing ⚠️
...se/sidebar/sidebars/course-outline/SidebarUnit.jsx 81.81% 2 Missing ⚠️
src/courseware/data/utils.js 96.00% 2 Missing ⚠️
...r/sidebars/course-outline/CourseOutlineTrigger.jsx 95.23% 1 Missing ⚠️
src/courseware/data/slice.js 96.96% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1349      +/-   ##
==========================================
+ Coverage   88.28%   88.60%   +0.31%     
==========================================
  Files         292      312      +20     
  Lines        5002     5238     +236     
  Branches     1269     1299      +30     
==========================================
+ Hits         4416     4641     +225     
- Misses        570      581      +11     
  Partials       16       16              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ihor-romaniuk
Copy link
Contributor Author

@arbrandes This PR will be closed due to open new PR without PluginSlots and managing the outline sidebar by Waffle flag #1375

@openedx-webhooks
Copy link

@ihor-romaniuk Even though your pull request wasn’t merged, please take a moment to answer a two question survey so we can improve your experience in the future.

@itsjeyd itsjeyd removed the waiting on author PR author needs to resolve review requests, answer questions, fix tests, etc. label May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
open-source-contribution PR author is not from Axim or 2U product review PR requires product review before merging
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

5 participants