diff --git a/i18n/en.pot b/i18n/en.pot index bb2f03c33..936f74c49 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -427,39 +427,6 @@ msgstr "Could not update interpretation" msgid "Enter interpretation text" msgstr "Enter interpretation text" -msgid "Bold text" -msgstr "Bold text" - -msgid "Italic text" -msgstr "Italic text" - -msgid "Link to a URL" -msgstr "Link to a URL" - -msgid "Mention a user" -msgstr "Mention a user" - -msgid "Add emoji" -msgstr "Add emoji" - -msgid "Preview" -msgstr "Preview" - -msgid "Back to write mode" -msgstr "Back to write mode" - -msgid "Too many results. Try refining the search." -msgstr "Too many results. Try refining the search." - -msgid "Search for a user" -msgstr "Search for a user" - -msgid "Searching for \"{{- searchText}}\"" -msgstr "Searching for \"{{- searchText}}\"" - -msgid "No results found" -msgstr "No results found" - msgid "Not available offline" msgstr "Not available offline" @@ -882,6 +849,27 @@ msgstr "Financial Years" msgid "Years" msgstr "Years" +msgid "Bold text" +msgstr "Bold text" + +msgid "Italic text" +msgstr "Italic text" + +msgid "Link to a URL" +msgstr "Link to a URL" + +msgid "Mention a user" +msgstr "Mention a user" + +msgid "Add emoji" +msgstr "Add emoji" + +msgid "Preview" +msgstr "Preview" + +msgid "Back to write mode" +msgstr "Back to write mode" + msgid "Interpretations and details" msgstr "Interpretations and details" @@ -912,6 +900,18 @@ msgstr "Could not load translations" msgid "Retry" msgstr "Retry" +msgid "Too many results. Try refining the search." +msgstr "Too many results. Try refining the search." + +msgid "Search for a user" +msgstr "Search for a user" + +msgid "Searching for \"{{- searchText}}\"" +msgstr "Searching for \"{{- searchText}}\"" + +msgid "No results found" +msgstr "No results found" + msgid "Series" msgstr "Series" diff --git a/package.json b/package.json index 68bdee192..57d596dfc 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,6 @@ "styled-jsx": "^4.0.1" }, "dependencies": { - "@dhis2/d2-ui-rich-text": "^7.4.1", "@dhis2/multi-calendar-dates": "1.0.0", "@dnd-kit/core": "^6.0.7", "@dnd-kit/sortable": "^7.0.2", @@ -71,6 +70,7 @@ "d3-color": "^1.2.3", "highcharts": "^10.3.3", "lodash": "^4.17.21", + "markdown-it": "^13.0.1", "mathjs": "^9.4.2", "react-beautiful-dnd": "^10.1.1", "resize-observer-polyfill": "^1.5.1" diff --git a/src/components/AboutAOUnit/AboutAOUnit.js b/src/components/AboutAOUnit/AboutAOUnit.js index 0d734efc1..1e2d77ab1 100644 --- a/src/components/AboutAOUnit/AboutAOUnit.js +++ b/src/components/AboutAOUnit/AboutAOUnit.js @@ -4,7 +4,6 @@ import { useTimeZoneConversion, } from '@dhis2/app-runtime' import i18n from '@dhis2/d2-i18n' -import { Parser as RichTextParser } from '@dhis2/d2-ui-rich-text' import { Button, CircularLoader, @@ -29,6 +28,7 @@ import React, { useImperativeHandle, } from 'react' import { formatList } from '../../modules/list.js' +import { RichTextParser } from '../RichText/index.js' import styles from './styles/AboutAOUnit.style.js' import { getTranslatedString, AOTypeMap } from './utils.js' @@ -191,7 +191,7 @@ const AboutAOUnit = forwardRef(({ type, id, renderId }, ref) => { )} {data && (
-

{ {data.ao.displayDescription} ) : ( - i18n.t('No description') +

{i18n.t('No description')}

)} -

+

diff --git a/src/components/Interpretations/InterpretationModal/CommentAddForm.js b/src/components/Interpretations/InterpretationModal/CommentAddForm.js index 9cae2d4a7..0b8f98498 100644 --- a/src/components/Interpretations/InterpretationModal/CommentAddForm.js +++ b/src/components/Interpretations/InterpretationModal/CommentAddForm.js @@ -3,8 +3,8 @@ import i18n from '@dhis2/d2-i18n' import { Button } from '@dhis2/ui' import PropTypes from 'prop-types' import React, { useRef, useState } from 'react' +import { RichTextEditor } from '../../RichText/index.js' import { - RichTextEditor, MessageEditorContainer, MessageButtonStrip, MessageInput, diff --git a/src/components/Interpretations/InterpretationModal/CommentUpdateForm.js b/src/components/Interpretations/InterpretationModal/CommentUpdateForm.js index ea9d3812e..dc90d2175 100644 --- a/src/components/Interpretations/InterpretationModal/CommentUpdateForm.js +++ b/src/components/Interpretations/InterpretationModal/CommentUpdateForm.js @@ -3,11 +3,8 @@ import i18n from '@dhis2/d2-i18n' import { Button, spacers, colors } from '@dhis2/ui' import PropTypes from 'prop-types' import React, { useState, useRef } from 'react' -import { - MessageEditorContainer, - RichTextEditor, - MessageButtonStrip, -} from '../common/index.js' +import { RichTextEditor } from '../../RichText/index.js' +import { MessageEditorContainer, MessageButtonStrip } from '../common/index.js' export const CommentUpdateForm = ({ interpretationId, diff --git a/src/components/Interpretations/InterpretationsUnit/InterpretationForm.js b/src/components/Interpretations/InterpretationsUnit/InterpretationForm.js index 2b7e9d02c..c6467a453 100644 --- a/src/components/Interpretations/InterpretationsUnit/InterpretationForm.js +++ b/src/components/Interpretations/InterpretationsUnit/InterpretationForm.js @@ -3,11 +3,8 @@ import i18n from '@dhis2/d2-i18n' import { Button, Input } from '@dhis2/ui' import PropTypes from 'prop-types' import React, { useRef, useState } from 'react' -import { - RichTextEditor, - MessageEditorContainer, - MessageButtonStrip, -} from '../common/index.js' +import { RichTextEditor } from '../../RichText/index.js' +import { MessageEditorContainer, MessageButtonStrip } from '../common/index.js' export const InterpretationForm = ({ type, @@ -46,7 +43,7 @@ export const InterpretationForm = ({ dataTest="interpretation-form" > {showRichTextEditor ? ( -

+ <> -
+ ) : ( setShowRichTextEditor(true)} diff --git a/src/components/Interpretations/common/Interpretation/InterpretationUpdateForm.js b/src/components/Interpretations/common/Interpretation/InterpretationUpdateForm.js index cf900fdf1..9891d7052 100644 --- a/src/components/Interpretations/common/Interpretation/InterpretationUpdateForm.js +++ b/src/components/Interpretations/common/Interpretation/InterpretationUpdateForm.js @@ -3,9 +3,9 @@ import i18n from '@dhis2/d2-i18n' import { Button, spacers, colors } from '@dhis2/ui' import PropTypes from 'prop-types' import React, { useState } from 'react' +import { RichTextEditor } from '../../../RichText/index.js' import { MessageEditorContainer, - RichTextEditor, MessageButtonStrip, InterpretationSharingLink, } from '../index.js' diff --git a/src/components/Interpretations/common/Message/Message.js b/src/components/Interpretations/common/Message/Message.js index 016e8b9d0..94bd37b5a 100644 --- a/src/components/Interpretations/common/Message/Message.js +++ b/src/components/Interpretations/common/Message/Message.js @@ -1,9 +1,9 @@ import { useTimeZoneConversion } from '@dhis2/app-runtime' -import { Parser as RichTextParser } from '@dhis2/d2-ui-rich-text' import { UserAvatar, spacers, colors } from '@dhis2/ui' import moment from 'moment' import PropTypes from 'prop-types' import React from 'react' +import { RichTextParser } from '../../../RichText/index.js' const Message = ({ children, text, created, username }) => { const { fromServerDate } = useTimeZoneConversion() diff --git a/src/components/Interpretations/common/Message/MessageEditorContainer.js b/src/components/Interpretations/common/Message/MessageEditorContainer.js index b4c7ff338..4de5bec5d 100644 --- a/src/components/Interpretations/common/Message/MessageEditorContainer.js +++ b/src/components/Interpretations/common/Message/MessageEditorContainer.js @@ -19,6 +19,7 @@ const MessageEditorContainer = ({ children, currentUser, dataTest }) => ( } .editor { flex-grow: 1; + height: 100%; } `}
diff --git a/src/components/Interpretations/common/RichTextEditor/index.js b/src/components/Interpretations/common/RichTextEditor/index.js deleted file mode 100644 index 31c0113ca..000000000 --- a/src/components/Interpretations/common/RichTextEditor/index.js +++ /dev/null @@ -1 +0,0 @@ -export { RichTextEditor } from './RichTextEditor.js' diff --git a/src/components/Interpretations/common/index.js b/src/components/Interpretations/common/index.js index 562614fb1..d3473298f 100644 --- a/src/components/Interpretations/common/index.js +++ b/src/components/Interpretations/common/index.js @@ -1,4 +1,3 @@ export * from './Interpretation/index.js' export * from './Message/index.js' -export * from './RichTextEditor/index.js' export * from './getInterpretationAccess.js' diff --git a/src/components/Interpretations/common/RichTextEditor/RichTextEditor.js b/src/components/RichText/Editor/Editor.js similarity index 78% rename from src/components/Interpretations/common/RichTextEditor/RichTextEditor.js rename to src/components/RichText/Editor/Editor.js index e8ad9216d..6fdbf558e 100644 --- a/src/components/Interpretations/common/RichTextEditor/RichTextEditor.js +++ b/src/components/RichText/Editor/Editor.js @@ -1,10 +1,9 @@ import i18n from '@dhis2/d2-i18n' -import { Parser as RichTextParser } from '@dhis2/d2-ui-rich-text' import { Button, Popover, Tooltip, - Field, + Help, IconAt24, IconFaceAdd24, IconLink24, @@ -12,9 +11,11 @@ import { IconTextItalic24, colors, } from '@dhis2/ui' +import cx from 'classnames' import PropTypes from 'prop-types' import React, { forwardRef, useRef, useEffect, useState } from 'react' -import { UserMentionWrapper } from '../UserMention/UserMentionWrapper.js' +import { UserMentionWrapper } from '../../UserMention/UserMentionWrapper.js' +import { Parser } from '../Parser/Parser.js' import { convertCtrlKey, insertMarkdown, @@ -33,22 +34,22 @@ import { toolbarClasses, tooltipAnchorClasses, emojisPopoverClasses, -} from './styles/RichTextEditor.style.js' +} from './styles/Editor.style.js' const EmojisPopover = ({ onInsertMarkdown, onClose, reference }) => ( @@ -190,29 +191,59 @@ Toolbar.propTypes = { disabled: PropTypes.bool, } -export const RichTextEditor = forwardRef( +export const Editor = forwardRef( ( - { value, disabled, inputPlaceholder, onChange, errorText, helpText }, + { + value, + disabled, + inputPlaceholder, + onChange, + errorText, + helpText, + initialFocus, + resizable, + }, externalRef ) => { const [previewMode, setPreviewMode] = useState(false) const internalRef = useRef() const textareaRef = externalRef || internalRef + const caretPosRef = useRef(undefined) - useEffect(() => textareaRef.current?.focus(), [textareaRef]) + const insertMarkdownCallback = (text, caretPos) => { + caretPosRef.current = caretPos + onChange(text) + textareaRef.current.focus() + } + + useEffect(() => { + if (initialFocus) { + textareaRef.current?.focus() + } + }, [initialFocus, textareaRef]) + + useEffect(() => { + if (caretPosRef.current) { + textareaRef.current?.setSelectionRange( + caretPosRef.current, + caretPosRef.current + ) + + caretPosRef.current = undefined + } + }, [value, textareaRef]) return ( -
+
{ insertMarkdown( markdown, textareaRef.current, - (text, caretPos) => { - onChange(text) - textareaRef.current.focus() - textareaRef.current.selectionEnd = caretPos - } + insertMarkdownCallback ) if (markdown === MENTION) { @@ -231,20 +262,18 @@ export const RichTextEditor = forwardRef( /> {previewMode ? (
- {value} + {value}
) : ( - +