From eb469f84f643e8043bec724a7d3fc4e4162042d8 Mon Sep 17 00:00:00 2001 From: TWIINE <122885804+Twiineenock@users.noreply.github.com> Date: Sat, 7 Dec 2024 00:23:09 +0300 Subject: [PATCH] (feat) O3-3946: Add support for markdown questions (#355) * feat: Add support from markdown questions * Fix conditional statements --------- Co-authored-by: Nethmi Rodrigo --- .eslintignore | 2 +- .eslintrc | 1 + __mocks__/react-markdown.tsx | 5 + jest.config.js | 1 + package.json | 2 + .../add-question.modal.tsx | 104 ++--- .../draggable-question.component.tsx | 5 +- .../draggable-question.scss | 2 +- .../edit-question.modal.tsx | 102 ++--- .../interactive-builder.component.tsx | 64 +-- .../interactive-builder.scss | 2 +- .../markdown-question.component.tsx | 52 +++ .../markdown-question.scss | 372 ++++++++++++++++++ .../interactive-builder/markdown-wrapper.tsx | 43 ++ src/config-schema.ts | 1 + src/types.ts | 4 +- yarn.lock | 12 + 17 files changed, 641 insertions(+), 133 deletions(-) create mode 100644 __mocks__/react-markdown.tsx create mode 100644 src/components/interactive-builder/markdown-question.component.tsx create mode 100644 src/components/interactive-builder/markdown-question.scss create mode 100644 src/components/interactive-builder/markdown-wrapper.tsx diff --git a/.eslintignore b/.eslintignore index 70f565b8..2b80a521 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,4 @@ **/dist/* **/node_modules/* **/*.d.tsx -__mocks__/* +__mocks__/* \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index eef523ff..90988c21 100644 --- a/.eslintrc +++ b/.eslintrc @@ -21,6 +21,7 @@ "import/no-duplicates": "error", "react-hooks/exhaustive-deps": "warn", "react-hooks/rules-of-hooks": "error", + "@typescript-eslint/no-explicit-any": "off", // not hugely concerned about accidental implicit type coercions for now https://typescript-eslint.io/rules/no-base-to-string "@typescript-eslint/no-base-to-string": "off", // The following rules need `noImplicitAny` to be set to `true` in our tsconfig. They are too restrictive for now, but should be reconsidered in future diff --git a/__mocks__/react-markdown.tsx b/__mocks__/react-markdown.tsx new file mode 100644 index 00000000..430fb008 --- /dev/null +++ b/__mocks__/react-markdown.tsx @@ -0,0 +1,5 @@ +import React from 'react'; + +export default function ({ children }) { + return <>{children}; +} diff --git a/jest.config.js b/jest.config.js index 2aeb643a..bba5829e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -14,6 +14,7 @@ module.exports = { 'lodash-es': 'lodash', '^dexie$': '/node_modules/dexie', '^react-i18next$': '/__mocks__/react-i18next.js', + 'react-markdown': '/__mocks__/react-markdown.tsx', }, setupFilesAfterEnv: ['/src/setup-tests.ts'], testEnvironment: 'jsdom', diff --git a/package.json b/package.json index 4bfc6293..bae61adc 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,8 @@ "fuzzy": "^0.1.3", "lodash-es": "^4.17.21", "react-ace": "^11.0.1", + "react-markdown": "^9.0.1", + "react-mde": "^11.5.0", "sass": "^1.67.0" }, "peerDependencies": { diff --git a/src/components/interactive-builder/add-question.modal.tsx b/src/components/interactive-builder/add-question.modal.tsx index 110f8a9a..a7e48705 100644 --- a/src/components/interactive-builder/add-question.modal.tsx +++ b/src/components/interactive-builder/add-question.modal.tsx @@ -47,6 +47,7 @@ import { useConceptLookup } from '../../hooks/useConceptLookup'; import { usePatientIdentifierTypes } from '../../hooks/usePatientIdentifierTypes'; import { usePersonAttributeTypes } from '../../hooks/usePersonAttributeTypes'; import { useProgramWorkStates, usePrograms } from '../../hooks/useProgramStates'; +import MarkdownQuestion from './markdown-question.component'; import styles from './question-modal.scss'; interface AddQuestionModalProps { @@ -109,6 +110,7 @@ const AddQuestionModal: React.FC = ({ const [min, setMin] = useState(''); const [questionId, setQuestionId] = useState(''); const [questionLabel, setQuestionLabel] = useState(''); + const [questionValue, setQuestionValue] = useState(''); const [questionType, setQuestionType] = useState(null); const [rows, setRows] = useState(''); const [selectedAnswers, setSelectedAnswers] = useState< @@ -149,7 +151,6 @@ const AddQuestionModal: React.FC = ({ const [toggleLabelFalse, setToggleLabelFalse] = useState(''); const renderTypeOptions = { - control: ['text'], encounterDatetime: ['date'], encounterLocation: ['ui-select-extended'], encounterProvider: ['ui-select-extended'], @@ -250,8 +251,9 @@ const AddQuestionModal: React.FC = ({ const computedQuestionId = `question${questionIndex + 1}Section${sectionIndex + 1}Page-${pageIndex + 1}`; const newQuestion = { - label: questionLabel, - type: questionType, + ...(questionLabel && {label: questionLabel}), + ...((renderingType === 'markdown') && {value: questionValue}), + type: questionType ? questionType : 'control', required: isQuestionRequired, id: questionId ?? computedQuestionId, ...((renderingType === 'date' || renderingType === 'datetime') && @@ -361,14 +363,15 @@ const AddQuestionModal: React.FC = ({ - : ( + } placeholder={t('labelPlaceholder', 'e.g. Type of Anaesthesia')} value={questionLabel} onChange={(event: React.ChangeEvent) => setQuestionLabel(event.target.value)} - required /> + )} = ({ required /> - - setIsQuestionRequired(false)} - value="optional" - /> - setIsQuestionRequired(true)} - value="required" - /> - - - + {renderingType !== 'markdown' && ( + <> + + setIsQuestionRequired(false)} + value="optional" + /> + setIsQuestionRequired(true)} + value="required" + /> + + + + )} {questionType === 'personAttribute' && ( @@ -1003,7 +1010,6 @@ const AddQuestionModal: React.FC = ({