Skip to content

Conversation

@tecoholic
Copy link
Contributor

@tecoholic tecoholic commented Mar 10, 2025

Description

The PR adds new frontend plugin slots for adding in-context metrics to Studio.

Following the convention established in frontend-app-learner-dashboard,
the new slots are defined in the src/plugin-slots directory. They are then
imported at the appropriate components as expected in the UI. The components
that would provide the metrics from Superset (Aspects) are added to the
repository as plugins in the plugins/aspects directory. They will be
inserted in the slots by tutor-contrib-aspects.
However, these plugins can be manually inserted into the slots by configuring
them in env.config.jsx for dev or testing purposes.

Design decisions and their rationales should be documented in the repo (docstring / ADR), per

Useful information to include:

  • Which edX user roles will this change impact? Course Author
  • Include screenshots for changes to the UI (ideally, both "before" and "after" screenshots, if applicable). TODO

Supporting information

  1. https://openedx.org/blog/axim-funded-contribution-in-context-metrics-for-studio/
  2. https://discuss.openedx.org/t/deadline-extended-to-2-7-axim-funded-contribution-to-add-in-context-metrics-to-studio/14817

Testing instructions

Setup with tutor-contrib-aspects

Warning

This no longer works as the plugins have been moved out. See below for setting up without tutor-contrib-aspects.

  1. Setup a tutor-main environment.
  2. Install tutor-contrib-aspects from the PR branch at In-context metrics for studio tutor-contrib-aspects#1030
  3. Run tutor config save to generate the necessary configuration.
  4. Clone this repo and switch to the PR branch.
  5. Copy the generated env.config.jsx into the repo. This is needed as tutor mounts for MFE repos replace the container
    directory with your local directory, which results in env.config.jsx getting overwritten or removed
    .
    cp $(tutor config printroot)env/plugins/mfe/build/mfe/env.config.jsx /your/path/to/frontend-app-authoring
    
  6. Add the repo as tutor mount.

Setup without tutor-contrib-aspects

  1. Clone the repo and switch to PR branch
  2. Add the following to env.config.jsx inside the repo. (create the file if needed)
import { PLUGIN_OPERATIONS, DIRECT_PLUGIN } from '@openedx/frontend-plugin-framework';
import { Button, IconButton } from '@openedx/paragon';
import { AutoGraph } from '@openedx/paragon/icons';

// Load environment variables from .env file
const config = {
  ...process.env,
  pluginSlots: {
    course_outline_header_actions_slot: {
      keepDefault: true,
      plugins: [
        {
          op: PLUGIN_OPERATIONS.Insert,
          widget: {
            id: 'outline-analytics',
            type: DIRECT_PLUGIN,
            priority: 51,
            RenderWidget: () => (<Button>Analytics</Button>),
          },
        },
      ],
    },
    course_unit_header_actions_slot: {
      keepDefault: true,
      plugins: [
        {
          op: PLUGIN_OPERATIONS.Insert,
          widget: {
            id: 'unit-analytics',
            type: DIRECT_PLUGIN,
            priority: 51,
            RenderWidget: () => (<Button>Analytics</Button>),
          }
        },
      ]
    },
    course_outline_unit_card_extra_actions_slot: {
      keepDefault: true,
      plugins: [
        {
          op: PLUGIN_OPERATIONS.Insert,
          widget: {
            id: 'uni-card-my-extra-action',
            type: DIRECT_PLUGIN,
            priority: 51,
            RenderWidget: () => (<IconButton iconAs={AutoGraph} alt="Graph Icon" />),
          }
        }
      ]
    },
    course_outline_subsection_card_extra_actions_slot: {
      keepDefault: true,
      plugins: [
        {
          op: PLUGIN_OPERATIONS.Insert,
          widget: {
            id: 'sub-card-my-extra-action',
            type: DIRECT_PLUGIN,
            priority: 51,
            RenderWidget: () => (<IconButton iconAs={AutoGraph} alt="Graph Icon" />),
          }
        }
      ]
    }
  },
};

export default config;
  1. Add the repo as a tutor mount.

Both the scenarios will have a workable env.config.jsx in your repo and ready to go. Now,
build the authoring-dev container and start it. tutor images build authoring-dev,
tutor dev stop authroing && tutor dev start authoring -d

Course Outline Analytics

The course outline page should now have an "Analytics" button, without any extra steps.

Course Unit Analytics

By default, the Authoring MFE uses legacy Studio UI for the Course Unit page. In order to test the
PR changes, enable the MFE's course unit page.

  1. Create a Course Waffle Flag in the LMS admin (/admin/waffle_utils/waffleflagcourseoverridemodel/) with:
    • Waffle Flag: contentstore.new_studio_mfe.use_new_unit_page
    • Course ID: The ID of the course you are using for testing.
    • Override Choice: Force ON
    • Enabled: Check
  2. Add a .env.private in the MFE repo with the following
ENABLE_UNIT_PAGE=true

Now Authoring MFE should display the course units withing the MFE and the header should have an "Analytics" button.

Other information

Include anything else that will help reviewers and consumers understand the change.

  • Does this change depend on other changes elsewhere?
  • Any special concerns or limitations? For example: deprecations, migrations, security, or accessibility.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Mar 10, 2025
@openedx-webhooks
Copy link

openedx-webhooks commented Mar 10, 2025

Thanks for the pull request, @tecoholic!

This repository is currently maintained by @openedx/2u-tnl.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

Details
Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@github-project-automation github-project-automation bot moved this to Needs Triage in Contributions Mar 10, 2025
@tecoholic tecoholic marked this pull request as draft March 10, 2025 08:44
@tecoholic tecoholic changed the title [WIP] feat: adds the CourseOutlineAnalyticsSlot feat: adds slots for in-context metrics in studio outline and unit views Mar 11, 2025
@tecoholic tecoholic marked this pull request as ready for review March 11, 2025 11:49
@tecoholic tecoholic requested a review from farhaanbukhsh March 11, 2025 11:49
@mphilbrick211 mphilbrick211 moved this from Needs Triage to Waiting on Author in Contributions Mar 11, 2025
@@ -0,0 +1,22 @@
# Aspects Plugins
Copy link

Choose a reason for hiding this comment

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

Our hope here was that this plugin wouldn't need to reside here, but rather would be able to live in one of the Aspects repos (platform-plugin-aspects or tutor-contrib-aspects). Is that possible to do?

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 agree. I wasn't sure where to put this as well, I was hoping @farhaanbukhsh would give me some ideas during our internal review :)

On the tech side, as long as can install it as an NPM package any place should be good. The main side-effect I can think of would be to publish yet another NPM package.

Copy link
Member

Choose a reason for hiding this comment

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

Thank you @bmtcril for the review here, when I went through both repos:

  1. https://github.com/openedx/platform-plugin-aspects
  2. https://github.com/openedx/tutor-contrib-aspects/

It made more sense to me to move the plugins under tutor-contrib-aspect since it makes it a whole package of aspect configuration that we can ship and configure. Just like we have clickhouse, Ralph, Vector etc. we also ship a presentation layer(optional to use).

This also opens up the possibility of adding more such plugins there.

I went against the platform plugin aspect because these plugins installed there will make it a very confusing codebase. It will be good to keep all the customization in the tutor-plugin and the more concrete parts in the platform-plugin.

What do you think @tecoholic?

Copy link
Member

Choose a reason for hiding this comment

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

In a discussion yesterday, @bmtcril pointed out the segregation in responsibilities between two repos. Where anything related to LMS/CMS belongs to the platform-plugin-aspect while tutor-contrib-aspects will have all the configurations.

@tecoholic any thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@farhaanbukhsh The separation of concerns sounds sensible to me.

@bmtcril Practically what would be appropriate in the case? Personally, I think publishing an NPM package like @openedx/frontend-plugin-aspects could be complementary to platform-plugin-aspects. It might mean it's own repo .Or maybe it shares a directory in "platform-plugin-aspects" repo? I am not clear on the logistics of this. Kindly advise. I will move the plugin code accordingly.

Copy link

Choose a reason for hiding this comment

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

@tecoholic @farhaanbukhsh I think what we've come up with on the Axim side is that this should probably live in its own repo (frontend-plugin-aspects) until we have a better way of combining front-end, back-end, and tutor plugins in one place. If that's good for you all I can create the new repo for you in the openedx org and make you the maintainers of it through the support portion of this contract.

That way we don't have to deal with moving it later and setting up all of the automation, and I believe we can just grant you the permissions as the creators of the plugin (instead of going through the CC process).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bmtcril Great. Can you kindly create the repo and provide access to @farhaanbukhsh. As he is a CC, it should be fairly straightforward than my account without CC rights. He would be the primary reviewer for these changes from OpenCraft's side anyway.

Copy link
Member

Choose a reason for hiding this comment

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

@bmtcril gentle ping on creating the repo 😇

Copy link

Choose a reason for hiding this comment

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

I'm working on it now, it's going to start as a clone of frontend-template-application, but I know that won't be a perfect fit so feel free to adjust as necessary.

Copy link
Contributor

@brian-smith-tcril brian-smith-tcril left a comment

Choose a reason for hiding this comment

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

Context: I reviewed the plugin slots but not the plugins.

Overall these are looking really good! I'm super happy to see the plugin slots as components pattern being used so nicely!

I left a few comments in there. A couple of them are just little docs suggestions, and the other couple are some open questions about slot naming and flexibility.

Comment on lines 43 to 47
<CourseUnitAnalyticsSlot
unitTitle={unitTitle}
isUnitVerticalType={unitCategory === COURSE_BLOCK_NAMES.vertical.id}
courseVerticalChildren={courseVerticalChildren}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

Open questions:

  • Do we want to allow site operators to customize this beyond adding things at the end? If so, then it would make sense to have this slot wrap the existing buttons instead.
  • This slot is not analytics specific, any ideas for a more generic name for this slot?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@brian-smith-tcril Very valid comments.

  • Wrapping the full header navigation is an interesting idea. I think it might offer more flexibility in how this slot is used. I am onboard for this idea. @farhaanbukhsh what are your thoughts.
  • This was actually something I was planning to do. This should be something generic like CourseUnitHeaderActionsSlot and CourseOutlineHeaderActions slot. If there are better suggestions, kindly propose.

Copy link
Contributor

Choose a reason for hiding this comment

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

CourseUnitHeaderActionsSlot and CourseOutlineHeaderActionsSlot sound great to me!

Copy link
Member

Choose a reason for hiding this comment

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

Do we have multiple actions associated with them?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the idea is that the slot could wrap the current "actions" ("New section", "Reindex", "Collapse all", and "View live" in the Course Outline), and allow people to insert/modify them.

If we decide against wrapping the existing actions, and instead continue with slots with no default content, I think something like CourseOutlineHeaderAdditionalActionsSlot might work.

As for singular Action vs plural Actions - there is nothing stopping a site operator from putting multiple things into the slot.

const MyButtons = () => (
  <>
    <Button>foo</Button>
    <Button>bar</Button>
  </>
);
const config = {
  pluginSlots: {
    course_outline_analytics_slot: {
      keepDefault: true,
      plugins: [
        {
          op: PLUGIN_OPERATIONS.Insert,
          widget: {
            id: 'my-extra-button',
            priority: 60,
            type: DIRECT_PLUGIN,
            RenderWidget: MyButtons,
          },
        },
      ]
    }
  },
}

image

Copy link
Member

Choose a reason for hiding this comment

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

@brian-smith-tcril Awesome then it makes sense to have CourseUnitHeaderActionsSlot and CourseOutlineHeaderActionsSlot

{intl.formatMessage(messages.viewLiveButton)}
</Button>
</OverlayTrigger>
<CourseOutlineAnalyticsSlot hasSections={hasSections} sections={sections} />
Copy link
Contributor

Choose a reason for hiding this comment

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

Open questions:

  • Do we want to allow site operators to customize this beyond adding things at the end? If so, then it would make sense to have this slot wrap the existing buttons instead.
  • This slot is not analytics specific, any ideas for a more generic name for this slot?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replied above

@tecoholic
Copy link
Contributor Author

@brian-smith-tcril Thank you for your wonderful suggestions and comments. I have applied the suggestions and responded to your comments. I am planning on updating the PR after Farhaan's review.

@@ -0,0 +1,22 @@
# Aspects Plugins
Copy link
Member

Choose a reason for hiding this comment

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

Thank you @bmtcril for the review here, when I went through both repos:

  1. https://github.com/openedx/platform-plugin-aspects
  2. https://github.com/openedx/tutor-contrib-aspects/

It made more sense to me to move the plugins under tutor-contrib-aspect since it makes it a whole package of aspect configuration that we can ship and configure. Just like we have clickhouse, Ralph, Vector etc. we also ship a presentation layer(optional to use).

This also opens up the possibility of adding more such plugins there.

I went against the platform plugin aspect because these plugins installed there will make it a very confusing codebase. It will be good to keep all the customization in the tutor-plugin and the more concrete parts in the platform-plugin.

What do you think @tecoholic?

Comment on lines 43 to 47
<CourseUnitAnalyticsSlot
unitTitle={unitTitle}
isUnitVerticalType={unitCategory === COURSE_BLOCK_NAMES.vertical.id}
courseVerticalChildren={courseVerticalChildren}
/>
Copy link
Member

Choose a reason for hiding this comment

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

Do we have multiple actions associated with them?

} = headerNavigationsActions;

return (
<nav className="header-navigations ml-auto">
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: This wrapper wasn't needed as the SubHeader component already provides the necessary styling for the headerActions property.

@tecoholic tecoholic force-pushed the tecoholic/BB-9596-in-context-metrics-slot branch from 97c459c to 3e77134 Compare March 21, 2025 05:16
@tecoholic tecoholic requested a review from farhaanbukhsh March 21, 2025 05:22
Copy link
Member

@farhaanbukhsh farhaanbukhsh 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 asked additional question after testing in addition to this

missing_slot

these are the missing slots are we not planning to this in the same PR?

@codecov
Copy link

codecov bot commented Mar 25, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 93.46%. Comparing base (d1a6af5) to head (ed20892).
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1725   +/-   ##
=======================================
  Coverage   93.45%   93.46%           
=======================================
  Files        1120     1124    +4     
  Lines       22730    22746   +16     
  Branches     4916     4824   -92     
=======================================
+ Hits        21243    21259   +16     
  Misses       1419     1419           
  Partials       68       68           

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@farhaanbukhsh farhaanbukhsh left a comment

Choose a reason for hiding this comment

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

Great work the code looks beautiful and is working as expected. While I was going through the code and Figma design I noticed that on the unit page also we would need one more slot.

unit_edit

After this change the PR will be complete, sorry for the nitpicking here @tecoholic

@tecoholic
Copy link
Contributor Author

tecoholic commented Mar 26, 2025

@farhaanbukhsh Thanks for reviewing this once more and great catch on the missing slot in unit page. Frankly, I am the only who should be sorry for making you go through so many review rounds and missing the details. I will add the extra slot and ping you.

One point I forgot to mention, is that there are no tests for the slots in the Unit Card and Subsection card, because there is no functional code to generate test cases.

@tecoholic
Copy link
Contributor Author

@farhaanbukhsh I think that slot cannot be implemented at the moment. The content blocks are all rendered by the legacy Studio as an Iframe. The MFE won't be able to provide slots to add buttons in them.

Screenshot_20250326_200327

Also, this page is currently considered experimental and has to be enabled using a Course Level Waffle Flag. So, this might be possible only when we have these elements implemented in the MFE.

Copy link
Member

@farhaanbukhsh farhaanbukhsh left a comment

Choose a reason for hiding this comment

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

👍

  • ✅ I tested this on Tutor devstack and all the slots are working as expected
  • ✅ I read through the code
  • ❌ I checked for accessibility issues
  • ✅ Includes documentation

@farhaanbukhsh
Copy link
Member

@brian-smith-tcril can you have a look once? :)

@brian-smith-tcril
Copy link
Contributor

Overall this is looking great!

Would you be able to update the slot README files to include screenshots showing what the example plugins look like? This can also serve as a good way to double check the example plugin code works as expected with the slot changes.

@tecoholic
Copy link
Contributor Author

@brian-smith-tcril Absolutely. I have added the screenshots with the example configurations for all the slots and updated their READMEs.

@farhaanbukhsh
Copy link
Member

farhaanbukhsh commented Apr 3, 2025

@brian-smith-tcril Please have a look and if it looks good, can we merge this?
@tecoholic Can you please rebase the branch so that it is easy to merge without conflict?

@brian-smith-tcril
Copy link
Contributor

Once this is rebased and tests are passing I think it's good to merge!

tecoholic and others added 16 commits April 4, 2025 19:39
This commit introduces the dedicated folder to keep the slots of the MFE
This commit adds the slot and a plugin that can be inserted into the slot.

# Conflicts:
#	src/course-unit/header-navigations/HeaderNavigations.jsx
Co-authored-by: Brian Smith <112954497+brian-smith-tcril@users.noreply.github.com>
Co-authored-by: Brian Smith <112954497+brian-smith-tcril@users.noreply.github.com>
Co-authored-by: Brian Smith <112954497+brian-smith-tcril@users.noreply.github.com>
@tecoholic tecoholic force-pushed the tecoholic/BB-9596-in-context-metrics-slot branch from 190afcc to ed20892 Compare April 4, 2025 09:02
@tecoholic
Copy link
Contributor Author

@brian-smith-tcril I have rebased on master and the checks seems to have passed :)

@farhaanbukhsh
Copy link
Member

@tecoholic Do you mind squashing few of theses commits? I think bunch of the fixes or should I squash all of them into one? In that case can you give me a informative commit message?

@tecoholic
Copy link
Contributor Author

@farhaanbukhsh I thought about it during the rebase. I think it's okay to squash them all into one, as the change is adding slots and nothing more. I don't see a benefit in splitting into multiple commits.

@brian-smith-tcril brian-smith-tcril merged commit 15fcb55 into openedx:master Apr 4, 2025
7 checks passed
@github-project-automation github-project-automation bot moved this from Waiting on Author to Done in Contributions Apr 4, 2025
@xitij2000 xitij2000 deleted the tecoholic/BB-9596-in-context-metrics-slot branch April 9, 2025 08:26
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 opencraft-sandbox

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants