-
Notifications
You must be signed in to change notification settings - Fork 71
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
(feat) O3-3946: Add support for markdown questions #355
base: main
Are you sure you want to change the base?
(feat) O3-3946: Add support for markdown questions #355
Conversation
@Twiineenock could you please update your branch? |
<p className={styles.questionLabel}> | ||
<MarkdownWrapper markdown={question.label || question.value} /> | ||
</p> |
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.
Since the text shown in markdown can be quite long, unlike a question label, I don't think we should show the entirety of it here. Maybe we could just say Markdown content
, or something along those lines?
@denniskigen thoughts?
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.
@NethmiRodrigo , we have come up with this:
If the markdown is very long, we show a small part of the markdown plus ellipsis to show that there is more content.
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.
Lovely! Thanks @Twiineenock!
@@ -0,0 +1,54 @@ | |||
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.
Love that you made this into a component of its own! Thank you!
<Select | ||
defaultValue={questionToEdit.questionOptions.rendering} | ||
onChange={(event: React.ChangeEvent<HTMLSelectElement>) => setFieldType(event.target.value as RenderType)} | ||
id="renderingType" | ||
invalidText={t('validFieldTypeRequired', 'A valid field type value is required')} | ||
labelText={t('renderingType', 'Rendering type')} | ||
required | ||
> |
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'd prefer to have the question label be the first input in the modal, it feels more intuitive.
import styles from './markdown-question.scss'; | ||
|
||
interface MarkdownQuestionProps { | ||
palceHolder?: 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.
palceHolder?: string; | |
placeholder?: string; |
…k/openmrs-esm-form-builder into feat/support-for-markdown-qns
Hi @NethmiRodrigo, @denniskigen, I'm currently trying to import the react-mde styles directly from the library instead of rewriting them. However, I noticed that our Webpack configuration is enabling CSS Modules globally, which is likely scoping the CSS classes to components, making them unavailable for global styles like those from Here’s the relevant part of the Webpack configuration: const cssLoader = {
loader: require.resolve('css-loader'),
options: {
modules: {
localIdentName: `${ident}__[name]__[local]___[hash:base64:5]`,
},
},
}; I suspect that this configuration is preventing the How can we tweak the Webpack config to ensure that CSS Modules are applied to our local styles, but exclude the styles from Thanks! |
I can't seem to figure out why the e2e tests are failing, they pass perfectly fine locally. When creating a question, the save button in the modal stays disabled for some reason. Pinging @denniskigen for help |
@Twiineenock about this, with help from @ibacher, I changed the webpack config to overwrite the css rule, which is basically |
@Twiineenock lets opt to leave the styling as you've done. Although for future work, we should make the markdown editor match the carbon design system - https://carbondesignsystem.com/patterns/text-toolbar-pattern/. All that's left is figuring out why the e2e test isn't working. I doubt it has anything to do with your changes because they pass locally |
Woow, great Idea @NethmiRodrigo , Is it better when its a separate work? |
@Twiineenock if you would like to do it in this PR, we can go with that approach. I would prefer we get this in and do that work incrementally, since this feature works perfectly fine as is. About the e2e test, could you please update the |
Alright we shall do that incrementally |
Just a few final changes and we can merge this in @Twiineenock, could you also please update your branch? |
d79ef4e
to
6a4552b
Compare
src/types.ts
Outdated
type: string; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
value?: any; | ||
type?: 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.
We should revert making type to optional. That's probably why the build fails
src/types.ts
Outdated
@@ -63,8 +63,9 @@ export interface Schema { | |||
questions: Array<{ | |||
id: string; | |||
label?: string; | |||
value?:string; | |||
type: string; | |||
// eslint-disable-next-line @typescript-eslint/no-explicit-any |
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.
Rather than adding this as a comment, lets follow what has been done in the form engine and add this as a rule to the eslintrc file. See https://github.com/openmrs/openmrs-esm-form-engine-lib/blob/7f9a0813b1c69450e2cc0fcfa5222cd880b6033d/.eslintrc#L16
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.
Thanks, @NethmiRodrigo! Adding it directly to the .eslintrc
file, like in the form engine, was a great tip—appreciate the help!
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.
Actually, we would prefer that the no-explicit-any rule is enabled and disclaimed like this where it's unavoidable (although, for preference, use unknown
rather than any
).
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.
FWIW, the only reason its currently disabled in other repos is because historically we didn't enforce it.
Alrighty! Great work @Twiineenock! Could you update your branch and we'll merge this in! |
@@ -14,6 +14,7 @@ module.exports = { | |||
'lodash-es': 'lodash', | |||
'^dexie$': '<rootDir>/node_modules/dexie', | |||
'^react-i18next$': '<rootDir>/__mocks__/react-i18next.js', | |||
'react-markdown': '<rootDir>/__mocks__/react-markdown.tsx', |
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 don't love this type of mocking. It means that the tests cannot actually test this component. Is there a reason we need to stub it out like this?
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.
This is a very bad response from me to say this as the reason, but I did this following what we had done in form-engine, because jest threw an error.
<SelectItem text={questionType} value={questionType} key={key} /> | ||
))} | ||
</Select> | ||
{questionToEdit.questionOptions.rendering !== 'markdown' && ( |
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.
This seems very hacky. It probably makes sense to have some abstraction for "should render required fields" rather than just hard-coding "markdown" 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.
@ibacher I think it might be easier to add this into the refactor
<p className={styles.questionLabel}> | ||
{question.label ? question.label : <MarkdownWrapper markdown={question.value} />} | ||
</p> |
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.
This is an even weirder set of assumptions here, i.e., that any question without a label must be rendered via markdown. It would be better to check that the value is intended to be rendered in markdown.
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.
@ibacher , does this imply that question type value
can have other renderingType
s apart from markdown?
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.
Maybe in the future, probably. It would be better to check the rendering type === markdown as a condition.
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.
Updated this!
@@ -69,6 +70,45 @@ const DraggableQuestion: React.FC<DraggableQuestionProps> = ({ | |||
} | |||
}, [handleDuplicateQuestion, isDragging, question, pageIndex, sectionIndex]); | |||
|
|||
const MarkdownWrapper: React.FC<{ markdown: string | Array<string> }> = ({ markdown }) => { |
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.
Split this out as it's own component in it's own 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.
Updated this!
<SelectItem text={fieldType} value={fieldType} key={key} /> | ||
))} | ||
</Select> | ||
{'label' in questionToEdit && ( |
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.
</Select> | ||
</> | ||
)} | ||
{!questionToEdit.value && |
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 are we conditionally displaying the 'renderingType' field only when it has no value? If the intent is to prevent users from modifying the rendering type, we don't need to do that. Let's always display this field regardless.
Requirements
Summary
Description
This pull request introduces support for creating markdown-based questions within the interactive form builder. Markdown questions are designed for scenarios where additional explanatory content is needed within the form, apart from standard question labels. This content can help users understand how to fill out fields, explain the meaning of specific fields, or add other context. Since these questions are meant for accessibility and enhanced guidance, they do not contain fields to fill out.
Implementation Details
Currently, there is markdown rendering support in the
openmrs-esm-form-engine-lib
using react-markdown, which renders markdown strings as HTML elements within the UI.To provide full markdown support with editing capabilities, this PR includes the following key components:
Key Changes
UI Enhancements:
Integration with
form-engine
:openmrs-esm-form-engine-lib
to seamlessly integrate the markdown editor with existing question types.react-markdown
within the form engine to convert markdown text into React-rendered HTML elements.Features Added in this PR
By implementing this feature, the form builder now offers greater flexibility and accessibility, allowing clients to incorporate rich text explanations and formatting within their forms.
Technical Note: The core of this markdown support relies on
react-markdown
for rendering andreact-mde
for user editing. These libraries handle markdown safely and ensure React compatibility.Links
Screenshots
Screancasts
Creating a new question:
creat.webm
Edit an existing Question
edit-qn.webm
Related Issue
https://openmrs.atlassian.net/browse/O3-3946
Other