feat(learning): per-block content feedback slot wiring#83
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a per-block feedback drawer feature that can render either inline within the courseware sidebar column (sharing space with AskTIM) or as a right-side overlay, depending on the FEEDBACK_SLOT_MODE configuration. It adds several new components (FeedbackDrawerManagerSidebar, FeedbackDrawerSlot), a bundle loader (feedbackBundle.js), and a hook for enrichment data (useFeedbackEnrichment.js), while updating the sidebar coordinator and build configurations. The review feedback highlights a critical issue in SidebarAIDrawerCoordinator.jsx where window.postMessage is called using messageOrigin (the LMS origin) as the target origin. Because these messages are intended for the MFE window itself, this will cause browsers to block the messages in production environments where the MFE and LMS are hosted on different domains. The reviewer recommends updating these calls to use window.location.origin and removing messageOrigin from the affected useEffect dependency arrays.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| useEffect(() => { | ||
| if (prevUnitIdRef.current && prevUnitIdRef.current !== unitId && unitId !== null) { | ||
| // Only send close message if drawer is actually open | ||
| if (showAIDrawerRef.current) { | ||
| window.postMessage( | ||
| { | ||
| type: 'smoot-design::ai-drawer-close', | ||
| type: AI_DRAWER_CLOSE_MESSAGE, | ||
| }, | ||
| messageOrigin | ||
| ); | ||
| } | ||
| setShowAIDrawer(false); | ||
| // Auto-close feedback on unit change too (mirrors AskTIM). | ||
| if (FEEDBACK_SLOT_MODE) { | ||
| if (showFeedbackRef.current) { | ||
| window.postMessage({ type: FEEDBACK_CLOSE_MESSAGE }, messageOrigin); | ||
| } | ||
| setShowFeedback(false); | ||
| } | ||
| } | ||
| prevUnitIdRef.current = unitId; | ||
| }, [unitId, messageOrigin]); |
There was a problem hiding this comment.
Update the target origin to window.location.origin for both postMessage calls in this effect, and remove messageOrigin from the dependency array.
useEffect(() => {
if (prevUnitIdRef.current && prevUnitIdRef.current !== unitId && unitId !== null) {
// Only send close message if drawer is actually open
if (showAIDrawerRef.current) {
window.postMessage(
{
type: AI_DRAWER_CLOSE_MESSAGE,
},
window.location.origin
);
}
setShowAIDrawer(false);
// Auto-close feedback on unit change too (mirrors AskTIM).
if (FEEDBACK_SLOT_MODE) {
if (showFeedbackRef.current) {
window.postMessage({ type: FEEDBACK_CLOSE_MESSAGE }, window.location.origin);
}
setShowFeedback(false);
}
}
prevUnitIdRef.current = unitId;
}, [unitId]);There was a problem hiding this comment.
Pull request overview
This PR wires the Learning MFE legacy slot configuration to support per-block “Send feedback” UI by loading the @mitodl/smoot-design feedback drawer manager bundle either inline (in the notifications_discussions_sidebar.v1 sidebar column) or as a right-side overlay, depending on FEEDBACK_SLOT_MODE.
Changes:
- Adds feedback drawer slot components and a bundle loader (
feedbackBundle.js) to initialize thefeedbackDrawerManagerwith enrichment + authenticated submit client. - Extends
SidebarAIDrawerCoordinator.jsxto coordinate AskTIM vs. inline feedback visibility and share sticky-height behavior. - Updates
learning-mfe-config.env.jsxandbuild_config.yamlto mount/register the new slot files in the legacy build pipeline.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| deployments/mit-ol/mfe_slot_config/legacy/useFeedbackEnrichment.js | Provides a stable getter for enrichment fields (course/unit/url) for feedback submissions. |
| deployments/mit-ol/mfe_slot_config/legacy/SidebarAIDrawerCoordinator.jsx | Coordinates AskTIM vs inline feedback slot and shares sticky-height sizing logic. |
| deployments/mit-ol/mfe_slot_config/legacy/learning-mfe-config.env.jsx | Mounts feedback drawer manager via the learning MFE slot config (inline vs overlay by env). |
| deployments/mit-ol/mfe_slot_config/legacy/FeedbackDrawerSlot.jsx | Inline “slot mode” host that loads/initializes the feedback bundle into a container. |
| deployments/mit-ol/mfe_slot_config/legacy/FeedbackDrawerManagerSidebar.jsx | Overlay-mode initializer for the feedback drawer manager bundle. |
| deployments/mit-ol/mfe_slot_config/legacy/feedbackBundle.js | Dynamic import wrapper for the feedback drawer bundle path + message origin helper. |
| deployments/mit-ol/mfe_slot_config/legacy/build_config.yaml | Registers the new slot files for dagger call mfe build-legacy-configured (learning MFE). |
Wire the Learning MFE slots for the per-block "Send feedback" drawer, in the MIT OL legacy slot config consumed by build-legacy-configured: - FeedbackDrawerManagerSidebar.jsx (right-side overlay loader) and FeedbackDrawerSlot.jsx (inline AskTIM-column loader) load the smoot-design feedbackDrawerManager bundle; feedbackBundle.js reads FEEDBACK_SUBMIT_URL and the prod /learn/static bundle path; useFeedbackEnrichment.js merges course name, unit title and URL into the submitted record. - SidebarAIDrawerCoordinator.jsx coordinates the feedback drawer alongside AskTIM in the shared sidebar column (mutually exclusive) and shares the sticky-height behavior; AskTIM behavior is unchanged. Close messages target the MFE origin so browsers don't drop them cross-origin. - learning-mfe-config.env.jsx: feedback mounts with the AI-drawer slot (no separate enable flag); FEEDBACK_SLOT_MODE selects presentation. The LMS-side ol_openedx_feedback.feedback_enabled CourseWaffleFlag is the gate. - build_config.yaml: register the four new files in learning.extra_slot_files.
e3f801f to
9b9627e
Compare
What are the relevant tickets?
Per-block content feedback — Learning MFE slot wiring for RFC mitodl/hq#11812 (parent mitodl/hq#11629). Supersedes the earlier ol-infrastructure slot wiring (mitodl/ol-infrastructure#4776), which moves here.
Companion PRs:
mitodl/smoot-design#241— feedback drawer UI bundlemitodl/open-edx-plugins#813— in-iframe "Send feedback" triggermitodl/learn-ai#556— backend endpoint + modelDescription (What does it do?)
Wires the Learning MFE slots for the per-block "Send feedback" drawer, in the MIT OL legacy slot config consumed by
dagger call mfe build-legacy-configured.FeedbackDrawerManagerSidebar.jsx— right-side overlay loader.FeedbackDrawerSlot.jsx— inline loader (renders in the AskTIM sidebar column).feedbackBundle.js— loads the smoot-designfeedbackDrawerManagerbundle (prod/learn/static/…) and readsFEEDBACK_SUBMIT_URL.useFeedbackEnrichment.js— merges course name, unit title, and current URL into the submitted record.SidebarAIDrawerCoordinator.jsx— coordinates the feedback drawer alongside AskTIM in the sharednotifications_discussions_sidebar.v1column (mutually exclusive), sharing the sticky-height behavior. AskTIM behavior is unchanged; coordinationpostMessages target the MFE origin so browsers don't drop them cross-origin.learning-mfe-config.env.jsx— feedback mounts with the AI-drawer slot (no separate enable flag);FEEDBACK_SLOT_MODEselects presentation (inline column vs right-side overlay). The per-course gate is the LMS-sideol_openedx_feedback.feedback_enabledCourseWaffleFlag.build_config.yaml— registers the four new files inlearning.extra_slot_files.The feedback drawer UI ships in
@mitodl/smoot-design; the in-iframe trigger ships inol_openedx_feedback. This PR is the MFE slot wiring only.How can this be tested?
Prereqs in the LMS:
ol_openedx_feedbackinstalled, with theol_openedx_feedback.feedback_enabledCourseWaffleFlag enabled.feedbackDrawerManagerbundle available at/learn/static/smoot-design/feedbackDrawerManager.es.js.ENABLE_AI_DRAWER_SLOT=true;FEEDBACK_SUBMIT_URLpointing at learn-ai's/api/v0/content_feedback/.Steps:
dagger call mfe build-legacy-configured --deployment-name mitxonline --release-name <release>.course_id, course_name, block_usage_key, block_type, block_display_name, unit_title, url, sentiment, comment) toFEEDBACK_SUBMIT_URL.Additional Context
notifications_discussions_sidebar.v1slot and are mutually exclusive in that column..ulmocoordinator variant (SidebarAIDrawerCoordinator.ulmo.jsx) does not yet carry the feedback coordination — parity follow-up if the Ulmo release needs it.ContentFeedbackmodel +POST /api/v0/content_feedback/) lives in learn-ai (#556).