-
Notifications
You must be signed in to change notification settings - Fork 172
feat: Add HTML and Problem editors plugin slots #2749
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
base: master
Are you sure you want to change the base?
feat: Add HTML and Problem editors plugin slots #2749
Conversation
|
Thanks for the pull request, @KyryloKireiev! This repository is currently maintained by 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 approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo 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:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. 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:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
PKulkoRaccoonGang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ll review this in more detail later, but based on a quick pass, the following updates are needed:
- Remove
AILab-146from the PR title. - Consider my suggestion about using import aliases for the new imports introduced in this PR’s diff.
- Review the proposal regarding avoiding the use of
React.FC<>.
|
|
||
| import { selectors } from '../../../../data/redux'; | ||
| import { selectors, actions } from '../../../../data/redux'; | ||
| import { getDataFromOlx } from '../../../../data/redux/thunkActions/problem'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use frontend-aliases for new imports in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently additional imports removed due to ProblemEditorPluginSlot refactored
| export const TextEditorPluginSlot: React.FC<TextEditorPluginSlotProps> = ({ | ||
| updateContent, | ||
| blockType, | ||
| }) => ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[optional]: I’m not a big fan of declaring types using React.FC. Also, looking at the other slots in this repository, they are defined without FC. To keep things consistent, I suggest following the same pattern:
| export const TextEditorPluginSlot: React.FC<TextEditorPluginSlotProps> = ({ | |
| updateContent, | |
| blockType, | |
| }) => ( | |
| export const TextEditorPluginSlot = ({ | |
| updateContent, | |
| blockType, | |
| }: TextEditorPluginSlotProps) => ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied
| updateContent={(newOLX) => { | ||
| // Parse and update the problem state | ||
| const rawSettings = { | ||
| weight: problemState.settings?.scoring?.weight || 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the default height 1 and not 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updateContent removed from plugin slot and moved in Plugin implementation.
by default we use weight == 1 for Problem xBlock
| showanswer: problemState.settings?.showAnswer?.on || null, | ||
| show_reset_button: problemState.settings?.showResetButton || null, | ||
| rerandomize: problemState.settings?.randomization || null, | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[important]: You are using ||, which means that valid falsy values (0, false) will be replaced with defaults
weight: 0 -> 1
showAnswer.on: false-> null
Let's use nullish coalescing (??) instead of logical OR ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also moved to AIAssistantWidget component.
Changed to ?? in AIAssistantWidget component.
| ) : ( | ||
| <span className="flex-grow-1 mb-5"> | ||
| <ProblemEditorPluginSlot | ||
| updateContent={(newOLX) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[optional]: In this file, I didn’t notice this, but it would be good to introduce a new updateProblemEditorContent function and move all logic related to updating the content for ProblemEditorPluginSlot into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function updateContent removed from ProblemEditorPluginSlot
| <> | ||
| <TextEditorPluginSlot | ||
| updateContent={(newContent) => { | ||
| // Update the editor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that, based on the updateContent prop name, it’s already clear that this is responsible for updating the content. So let’s remove this comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
updateContent function also removed from TextEditorPluginSlot
| ) : ( | ||
| <> | ||
| <TextEditorPluginSlot | ||
| updateContent={(newContent) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[optional]: In this file, I didn’t notice this, but it would be good to introduce a new updateTextEditorContent function and move all logic related to updating the content for TextEditorPluginSlot into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updateContent removed
| - The `blockType` prop may be in different formats: | ||
| - API format: `problem-single-select`, `problem-multi-select`, etc. | ||
| - OLX format: `multiplechoiceresponse`, `choiceresponse`, etc. | ||
| - Generic: `problem`, `advanced` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be some code example here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed entirely, because ProblemEditorPluginSlot and TextEditorPluginSlot know nothing about possible backend implementation inserted plugin
| @@ -0,0 +1,36 @@ | |||
| import { PluginSlot } from '@openedx/frontend-plugin-framework/dist'; | |||
| import React from 'react'; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this React import?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
| interface TextEditorPluginSlotProps { | ||
| /** Function to update editor content with new content */ | ||
| updateContent: (content: string) => void; | ||
| /** Block type (e.g., 'html') */ | ||
| blockType: string; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| interface TextEditorPluginSlotProps { | |
| /** Function to update editor content with new content */ | |
| updateContent: (content: string) => void; | |
| /** Block type (e.g., 'html') */ | |
| blockType: string; | |
| } | |
| interface TextEditorPluginSlotProps { | |
| updateContent: (content: string) => void; | |
| blockType: string; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored
| /** | ||
| * Plugin slot for Text Editor (HTML xBlocks) | ||
| * | ||
| * Slot ID: `org.openedx.frontend.authoring.text_editor_plugin.v1` | ||
| * | ||
| * This slot allows plugins to add custom widgets to the HTML/text editor. | ||
| * By default, the slot is empty. Add widgets via `env.config.jsx`. | ||
| * | ||
| * Plugin Props: | ||
| * - `updateContent`: Function to update editor content with new content | ||
| * - `blockType`: Block type (e.g., 'html') | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reviewed several other plugin slots in this repository and didn’t find similar descriptive comments being added. I suggest removing this, since we already have a README.md file next to this plugin slot that documents all the necessary information about the plugin slot API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
|
|
||
| ## Example: Screenshot with custom implementation | ||
|
|
||
|  No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the documentation for this plugin slot, let’s also follow the same structure used by other plugin slots in this repository. Images should be placed under a heading with the name of the corresponding example.
src/editors/containers/ProblemEditor/components/EditProblemView/index.jsx
Outdated
Show resolved
Hide resolved
| - **Advanced/Raw Editor Mode**: Where the widget can generate raw OLX or Markdown content that is directly inserted into the CodeMirror editor. | ||
|
|
||
| ## Example: Adding the AI Content Assistant | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don’t want to mention anything about the AI Assistant, should we update the other description as well?
|  | ||
|
|
||
| ### Example: Screenshots with passed component into plugin slot for Problem editor | ||
|  |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these images be placed under the corresponding usage example? And do we want to mention the AI Assistant Widget?
| blockType: string; | ||
| } | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this extra space?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
|
|
||
| ## Description | ||
|
|
||
| The slot is positioned in the Text Editor modal window for HTML XBlocks. It is suitable for adding AI-powered content generation tools or other editor enhancements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we write the plugin slot description in a more general way? I don’t think we need to focus on “AI-powered content generation tools,” since this slot can be used for anything.
|
|
||
| ### Example: Screenshot with default HTML Editor | ||
|
|
||
|  No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these images be placed under the usage example heading, following the pattern used in the documentation for other plugin slots?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks. I forgot a lot of the artifacts that were left over from the previous description, which included AI Assistant Widget. Now I deleted all artifacts and rewrite docs.
Co-authored-by: Peter Kulko <[email protected]>
Co-authored-by: Peter Kulko <[email protected]>
Description