From 3d27b8425de481a8b1c648246e810c79226da692 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Tue, 6 Feb 2024 11:24:02 +0530 Subject: [PATCH 01/36] migration-from-draft-js --- package.json | 3 + src/common/RichEditor.tsx | 6 +- .../WhatsAppEditor/WhatsAppEditor.module.css | 26 +++ .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 167 ++++++++++++----- .../Chat/ChatMessages/ChatInput/ChatInput.tsx | 19 +- yarn.lock | 177 ++++++++++++++++++ 6 files changed, 338 insertions(+), 60 deletions(-) diff --git a/package.json b/package.json index 0ec42df8f..9cbc7a754 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@glific/flow-editor": "^1.19.3-5", + "@lexical/react": "^0.13.1", "@mui/icons-material": "^5.15.6", "@mui/material": "^5.15.6", "@mui/x-date-pickers": "^6.19.2", @@ -41,6 +42,8 @@ "i18next-browser-languagedetector": "^7.2.0", "interweave": "^13.1.0", "interweave-autolink": "^5.1.1", + "lexical": "^0.13.1", + "lexical-beautiful-mentions": "^0.1.30", "pino": "^8.17.2", "pino-logflare": "^0.4.2", "react": "^18.2.0", diff --git a/src/common/RichEditor.tsx b/src/common/RichEditor.tsx index b796d820d..1117ad2a8 100644 --- a/src/common/RichEditor.tsx +++ b/src/common/RichEditor.tsx @@ -9,9 +9,9 @@ const regexForLink = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi; // Convert Draft.js to WhatsApp message format. -export const getPlainTextFromEditor = (editorState: any) => - editorState.getCurrentContent().getPlainText(); - +export const getPlainTextFromEditor = (editorState: any) => { + return editorState?.textContent; +}; export const getEditorFromContent = (text: string) => EditorState.createWithContent(ContentState.createFromText(text)); diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css index a9600a4fd..d33bb0247 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css @@ -28,3 +28,29 @@ span.emoji-mart-emoji { .emoji-mart-emoji { font-size: medium; } + +.editorInput { + resize: none; + font-size: 16px; + overflow: auto; + width: 100%; + min-height: 40px; + margin-top: 4px; + position: relative; + tab-size: 1; + outline: 0; + /* padding: 4px 10px; */ +} + +.editorPlaceholder { + color: #999; + overflow: hidden; + position: absolute; + text-overflow: ellipsis; + top: 45px; + left: 35px; + font-size: 15px; + user-select: none; + display: inline-block; + pointer-events: none; +} diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 9b1ea22c4..6e6ea16fa 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -1,7 +1,17 @@ import { useCallback } from 'react'; +import { useEffect } from 'react'; + import { RichUtils, getDefaultKeyBinding, Modifier, EditorState, Editor } from 'draft-js'; +import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; +import { ContentEditable } from '@lexical/react/LexicalContentEditable'; +import { $getSelection, $createTextNode } from 'lexical'; +import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; +import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; import { useResizeDetector } from 'react-resize-detector'; import { useTranslation } from 'react-i18next'; +import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW } from 'lexical'; import { getPlainTextFromEditor } from 'common/RichEditor'; import styles from './WhatsAppEditor.module.css'; @@ -48,63 +58,128 @@ export const WhatsAppEditor = ({ setEditorState(editorStateChange); }; - const handleKeyCommand = (command: string, editorStateChange: any) => { - // On enter, submit. Otherwise, deal with commands like normal. - if (command === 'enter') { - // Convert Draft.js to WhatsApp - sendMessage(getPlainTextFromEditor(editorStateChange)); - return 'handled'; - } + const onResize = useCallback((height: any) => { + handleHeightChange(height - 40); + }, []); - if (command === 'underline') { - return 'handled'; - } + const { ref } = useResizeDetector({ + refreshMode: 'debounce', + refreshRate: 1000, + onResize, + }); - if (command === 'bold') { - setEditorState(updatedValue('**', editorState)); - } else if (command === 'italic') { - setEditorState(updatedValue('__', editorState)); - } else { - const newState = RichUtils.handleKeyCommand(editorStateChange, command); - if (newState) { - setEditorState(newState); - return 'handled'; - } - } - return 'not-handled'; + const onError = (error: any) => { + console.error(error); }; - const keyBindingFn = (e: any) => { - // Shift-enter is by default supported. Only 'enter' needs to be changed. - if (e.keyCode === 13 && !e.nativeEvent.shiftKey) { - return 'enter'; - } - return getDefaultKeyBinding(e); + const exampleTheme = { + ltr: 'ltr', + rtl: 'rtl', + paragraph: 'editor-paragraph', + input: 'editor-input', + }; + + const initialConfig = { + namespace: 'MyEditor', + onError, + theme: exampleTheme, }; - const onResize = useCallback((width: number | undefined, height: number | undefined) => { - if (height) { - handleHeightChange(height - 40); + const onChange = (editorState: any) => { + setEditorState(editorState.toJSON()); + }; + + const handleFormatting = (text: string, formatter: string) => { + switch (formatter) { + case 'bold': + return `*${text}*`; + case 'italic': + return `_${text}_`; + case 'strikethrough': + return `~${text}~`; + default: + return text; } - }, []); + }; - const { ref } = useResizeDetector({ - refreshMode: 'debounce', - refreshRate: 1000, - onResize, - }); + function MyCustomAutoFocusPlugin() { + const [editor] = useLexicalComposerContext(); + + useEffect(() => { + // const sendMessageCommand = editor.registerCommand( + // KEY_ENTER_COMMAND, + // (event: KeyboardEvent) => { + // // Handle enter key presses here + // console.log('nf'); + + // // sendMessage(getPlainTextFromEditor(editor.getRootElement())); + // return false; + // }, + // COMMAND_PRIORITY_LOW + // ); + + // sendMessageCommand(); + + return editor.registerCommand( + KEY_DOWN_COMMAND, + (event: KeyboardEvent) => { + console.log(event); + + // Handle event here + let formatter = ''; + if (event.code === 'Enter' && !readOnly) { + event.preventDefault(); // Prevent line break on enter + // editor.update(() => { + // const emptyNode = createEmptyNode(); // Replace with your preferred empty node constructor + // editor.setEditorState( + // editor.createEditorState({ + // nodes: [emptyNode], + // }) + // ); + // }); + // sendMessage(getPlainTextFromEditor(editor.getRootElement())); + } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { + formatter = 'bold'; + } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { + formatter = 'italic'; + } + + // console.log(formatter); + + editor.update(() => { + const selection = $getSelection(); + if (selection?.getTextContent() && formatter) { + const text = handleFormatting(selection?.getTextContent(), formatter); + const newNode = $createTextNode(text); + selection?.insertNodes([newNode]); + } + }); + // console.log(event); + + return false; + }, + COMMAND_PRIORITY_LOW + ); + }, [editor, onChange]); + + return null; + } + function Placeholder() { + return
Type a message...
; + } return (
- + + } + contentEditable={} + ErrorBoundary={LexicalErrorBoundary} + /> + + +
); }; diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index b98744be5..e78ab843e 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -149,6 +149,7 @@ export const ChatInput = ({ }; setUploading(true); } + console.log(message); // check for an empty message or message with just spaces if ((!message || /^\s*$/.test(message)) && !attachmentAdded) return; @@ -177,16 +178,17 @@ export const ChatInput = ({ resetVariable(); // else the type will by default be text } else { + console.log('n'); + onSendMessage(message, null, 'TEXT', selectedTemplate, variableParam); resetVariable(); } // Resetting the EditorState - setEditorState( - EditorState.moveFocusToEnd( - EditorState.push(editorState, ContentState.createFromText(''), 'remove-range') - ) - ); + // setEditorState(''); + // EditorState.moveFocusToEnd( + // EditorState.push(editorState, ContentState.createFromText(''), 'remove-range') + // ) }; const emojiStyles = { @@ -490,12 +492,7 @@ export const ChatInput = ({ submitMessage(getPlainTextFromEditor(editorState)); } }} - disabled={ - (!editorState.getCurrentContent().hasText() && - !attachmentAdded && - !recordedAudio) || - uploading - } + // disabled={(!attachmentAdded && !recordedAudio) || uploading} > diff --git a/yarn.lock b/yarn.lock index c7d2a9d05..8e6fff47f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -757,6 +757,161 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@lexical/clipboard@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/clipboard/-/clipboard-0.13.1.tgz#ca132306129974ea2c9e51d6a8637f8fcffcdb3d" + integrity sha512-gMSbVeqb7S+XAi/EMMlwl+FCurLPugN2jAXcp5k5ZaUd7be8B+iupbYdoKkjt4qBhxmvmfe9k46GoC0QOPl/nw== + dependencies: + "@lexical/html" "0.13.1" + "@lexical/list" "0.13.1" + "@lexical/selection" "0.13.1" + "@lexical/utils" "0.13.1" + +"@lexical/code@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/code/-/code-0.13.1.tgz#e13688390582a4b63a639daff1f16bcb82aa854d" + integrity sha512-QK77r3QgEtJy96ahYXNgpve8EY64BQgBSnPDOuqVrLdl92nPzjqzlsko2OZldlrt7gjXcfl9nqfhZ/CAhStfOg== + dependencies: + "@lexical/utils" "0.13.1" + prismjs "^1.27.0" + +"@lexical/dragon@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/dragon/-/dragon-0.13.1.tgz#32ba02bff4d8f02a6317d874671ee0b0a2dcdc53" + integrity sha512-aNlqfif4//jW7gOxbBgdrbDovU6m3EwQrUw+Y/vqRkY+sWmloyAUeNwCPH1QP3Q5cvfolzOeN5igfBljsFr+1g== + +"@lexical/hashtag@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/hashtag/-/hashtag-0.13.1.tgz#eb273c199a0115ec0f0191c2449e97f512360f2e" + integrity sha512-Dl0dUG4ZXNjYYuAUR0GMGpLGsA+cps2/ln3xEmy28bZR0sKkjXugsu2QOIxZjYIPBewDrXzPcvK8md45cMYoSg== + dependencies: + "@lexical/utils" "0.13.1" + +"@lexical/history@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/history/-/history-0.13.1.tgz#3bb54716dc69779d3b35894bd72637a7fc2ed284" + integrity sha512-cZXt30MalEEiRaflE9tHeGYnwT1xSDjXLsf9M409DSU9POJyZ1fsULJrG1tWv2uFQOhwal33rve9+MatUlITrg== + dependencies: + "@lexical/utils" "0.13.1" + +"@lexical/html@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/html/-/html-0.13.1.tgz#e56035d0c6528ffb932390e0d3d357c82f69253a" + integrity sha512-XkZrnCSHIUavtpMol6aG8YsJ5KqC9hMxEhAENf3HTGi3ocysCByyXOyt1EhEYpjJvgDG4wRqt25xGDbLjj1/sA== + dependencies: + "@lexical/selection" "0.13.1" + "@lexical/utils" "0.13.1" + +"@lexical/link@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/link/-/link-0.13.1.tgz#f1c4c12c828c0251e5d7fb4fb336f2d62380fc57" + integrity sha512-7E3B2juL2UoMj2n+CiyFZ7tlpsdViAoIE7MpegXwfe/VQ66wFwk/VxGTa/69ng2EoF7E0kh+SldvGQDrWAWb1g== + dependencies: + "@lexical/utils" "0.13.1" + +"@lexical/list@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/list/-/list-0.13.1.tgz#461cb989157bdf4a43eaa8596fdb09df60d114ee" + integrity sha512-6U1pmNZcKLuOWiWRML8Raf9zSEuUCMlsOye82niyF6I0rpPgYo5UFghAAbGISDsyqzM1B2L4BgJ6XrCk/dJptg== + dependencies: + "@lexical/utils" "0.13.1" + +"@lexical/mark@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/mark/-/mark-0.13.1.tgz#084bb49a8bc1c5c5a4ed5c5d4a20c98ea85ec8b1" + integrity sha512-dW27PW8wWDOKFqXTBUuUfV+umU0KfwvXGkPUAxRJrvwUWk5RKaS48LhgbNlQ5BfT84Q8dSiQzvbaa6T40t9a3A== + dependencies: + "@lexical/utils" "0.13.1" + +"@lexical/markdown@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/markdown/-/markdown-0.13.1.tgz#1fd2efcacff4ce733682a8161a3f3d78dba37503" + integrity sha512-6tbdme2h5Zy/M88loVQVH5G0Nt7VMR9UUkyiSaicyBRDOU2OHacaXEp+KSS/XuF+d7TA+v/SzyDq8HS77cO1wA== + dependencies: + "@lexical/code" "0.13.1" + "@lexical/link" "0.13.1" + "@lexical/list" "0.13.1" + "@lexical/rich-text" "0.13.1" + "@lexical/text" "0.13.1" + "@lexical/utils" "0.13.1" + +"@lexical/offset@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/offset/-/offset-0.13.1.tgz#f37417822aef3dc81580d4abb96e43ba9d547225" + integrity sha512-j/RZcztJ7dyTrfA2+C3yXDzWDXV+XmMpD5BYeQCEApaHvlo20PHt1BISk7RcrnQW8PdzGvpKblRWf//c08LS9w== + +"@lexical/overflow@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/overflow/-/overflow-0.13.1.tgz#42c036dc3ad3eb929fda5aa0a00a725b74f72669" + integrity sha512-Uw34j+qG2UJRCIR+bykfFMduFk7Pc4r/kNt8N1rjxGuGXAsreTVch1iOhu7Ev6tJgkURsduKuaJCAi7iHnKl7g== + +"@lexical/plain-text@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/plain-text/-/plain-text-0.13.1.tgz#e7e713029443c30facce27b34836bf604cf92c0f" + integrity sha512-4j5KAsMKUvJ8LhVDSS4zczbYXzdfmgYSAVhmqpSnJtud425Nk0TAfpUBLFoivxZB7KMoT1LGWQZvd47IvJPvtA== + +"@lexical/react@^0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/react/-/react-0.13.1.tgz#6c35bf43e24560d2ca3aa2c6ff607ef37de87bac" + integrity sha512-Sy6EL230KAb0RZsZf1dZrRrc3+rvCDQWltcd8C/cqBUYlxsLYCW9s4f3RB2werngD/PtLYbBB48SYXNkIALITA== + dependencies: + "@lexical/clipboard" "0.13.1" + "@lexical/code" "0.13.1" + "@lexical/dragon" "0.13.1" + "@lexical/hashtag" "0.13.1" + "@lexical/history" "0.13.1" + "@lexical/link" "0.13.1" + "@lexical/list" "0.13.1" + "@lexical/mark" "0.13.1" + "@lexical/markdown" "0.13.1" + "@lexical/overflow" "0.13.1" + "@lexical/plain-text" "0.13.1" + "@lexical/rich-text" "0.13.1" + "@lexical/selection" "0.13.1" + "@lexical/table" "0.13.1" + "@lexical/text" "0.13.1" + "@lexical/utils" "0.13.1" + "@lexical/yjs" "0.13.1" + react-error-boundary "^3.1.4" + +"@lexical/rich-text@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/rich-text/-/rich-text-0.13.1.tgz#8251e81a3985a4d76bef027cf6c0dc90c661e4ec" + integrity sha512-HliB9Ync06mv9DBg/5j0lIsTJp+exLHlaLJe+n8Zq1QNTzZzu2LsIT/Crquk50In7K/cjtlaQ/d5RB0LkjMHYg== + +"@lexical/selection@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/selection/-/selection-0.13.1.tgz#466d7cd0ee1b04680bd949112f1f5cb6a6618efa" + integrity sha512-Kt9eSwjxPznj7yzIYipu9yYEgmRJhHiq3DNxHRxInYcZJWWNNHum2xKyxwwcN8QYBBzgfPegfM/geqQEJSV1lQ== + +"@lexical/table@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/table/-/table-0.13.1.tgz#814d3b8a2afb821aff151c92cce831809f9d67a1" + integrity sha512-VQzgkfkEmnvn6C64O/kvl0HI3bFoBh3WA/U67ALw+DS11Mb5CKjbt0Gzm/258/reIxNMpshjjicpWMv9Miwauw== + dependencies: + "@lexical/utils" "0.13.1" + +"@lexical/text@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/text/-/text-0.13.1.tgz#12104d42da7a707a19853679f3a88e8ed6ce8084" + integrity sha512-NYy3TZKt3qzReDwN2Rr5RxyFlg84JjXP2JQGMrXSSN7wYe73ysQIU6PqdVrz4iZkP+w34F3pl55dJ24ei3An9w== + +"@lexical/utils@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/utils/-/utils-0.13.1.tgz#f2a72f71c859933781294830b38b25b5b33122a9" + integrity sha512-AtQQKzYymkbOaQxaBXjRBS8IPxF9zWQnqwHTUTrJqJ4hX71aIQd/thqZbfQETAFJfC8pNBZw5zpxN6yPHk23dQ== + dependencies: + "@lexical/list" "0.13.1" + "@lexical/selection" "0.13.1" + "@lexical/table" "0.13.1" + +"@lexical/yjs@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@lexical/yjs/-/yjs-0.13.1.tgz#2a71ae3c4b3cc5c660bbe66d537eb0cbf3c7c1b6" + integrity sha512-4GbqQM+PwNTV59AZoNrfTe/0rLjs+cX6Y6yAdZSRPBwr5L3JzYeU1TTcFCVQTtsE7KF8ddVP8sD7w9pi8rOWLA== + dependencies: + "@lexical/offset" "0.13.1" + "@mui/base@5.0.0-beta.33": version "5.0.0-beta.33" resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.33.tgz#fbb844e2d840d47dd7a48850a03152aed2381d10" @@ -3909,6 +4064,16 @@ lead@^4.0.0: resolved "https://registry.yarnpkg.com/lead/-/lead-4.0.0.tgz#5317a49effb0e7ec3a0c8fb9c1b24fb716aab939" integrity sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg== +lexical-beautiful-mentions@^0.1.30: + version "0.1.30" + resolved "https://registry.yarnpkg.com/lexical-beautiful-mentions/-/lexical-beautiful-mentions-0.1.30.tgz#9b541115c690b9b43ed55441ed133d8e928bd253" + integrity sha512-2Hi8T8f4+kc/iCnVeglgl9spyEEuoi7gGQgeTQo3tA6wyPsA5HWPSg4yk39YtTE7kkucwzG3j8gqpCuerd3Lsg== + +lexical@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/lexical/-/lexical-0.13.1.tgz#0abffe9bc05a7a9da8a6128ea478bf08c11654db" + integrity sha512-jaqRYzVEfBKbX4FwYpd/g+MyOjRaraAel0iQsTrwvx3hyN0bswUZuzb6H6nGlFSjcdrc77wKpyKwoWj4aUd+Bw== + lilconfig@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.0.0.tgz#f8067feb033b5b74dab4602a5f5029420be749bc" @@ -4548,6 +4713,11 @@ pretty-format@^29.0.0, pretty-format@^29.7.0: ansi-styles "^5.0.0" react-is "^18.0.0" +prismjs@^1.27.0: + version "1.29.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" + integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -4681,6 +4851,13 @@ react-draggable@^4.4.6: clsx "^1.1.1" prop-types "^15.8.1" +react-error-boundary@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" + integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== + dependencies: + "@babel/runtime" "^7.12.5" + react-fast-compare@^2.0.1: version "2.0.4" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" From acbb45fab631ac5a0bfc5e2551b66911b7dc9d6a Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Thu, 8 Feb 2024 08:12:08 +0530 Subject: [PATCH 02/36] configured plugins --- src/common/RichEditor.tsx | 3 +- .../UI/Form/EmojiInput/EmojiInput.tsx | 16 +- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 22 -- src/containers/Form/FormLayout.tsx | 17 +- .../InteractiveMessage.helper.ts | 4 +- .../InteractiveMessage/InteractiveMessage.tsx | 2 +- src/containers/Template/Editor.module.css | 110 +++++++ src/containers/Template/Editor.tsx | 283 ++++++++++++++++++ src/containers/Template/Form/HSM/HSM.tsx | 7 +- src/containers/Template/Form/Template.tsx | 28 +- 10 files changed, 450 insertions(+), 42 deletions(-) create mode 100644 src/containers/Template/Editor.module.css create mode 100644 src/containers/Template/Editor.tsx diff --git a/src/common/RichEditor.tsx b/src/common/RichEditor.tsx index 1117ad2a8..ef4e43c7a 100644 --- a/src/common/RichEditor.tsx +++ b/src/common/RichEditor.tsx @@ -10,7 +10,7 @@ const regexForLink = // Convert Draft.js to WhatsApp message format. export const getPlainTextFromEditor = (editorState: any) => { - return editorState?.textContent; + return editorState; }; export const getEditorFromContent = (text: string) => EditorState.createWithContent(ContentState.createFromText(text)); @@ -86,6 +86,7 @@ export const WhatsAppToJsx = (text: any) => { export const WhatsAppTemplateButton = (text: string) => { const result: any = { body: text, buttons: null }; + console.log(text); // Returning early if text is null if (!text) return result; diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index 08c69d126..7e3737bee 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -1,12 +1,12 @@ import { useState, useMemo, useCallback, forwardRef } from 'react'; import { RichUtils, Modifier, EditorState, ContentState } from 'draft-js'; -import Editor from '@draft-js-plugins/editor'; import createMentionPlugin from '@draft-js-plugins/mention'; import { InputAdornment, IconButton, ClickAwayListener } from '@mui/material'; import { getPlainTextFromEditor } from 'common/RichEditor'; import { EmojiPicker } from 'components/UI/EmojiPicker/EmojiPicker'; import { Input } from '../Input/Input'; +import { Editor } from 'containers/Template/Editor'; import Styles from './EmojiInput.module.css'; export interface EmojiInputProps { @@ -122,12 +122,16 @@ export const EmojiInput = ({ }; const draftJsChange = (editorState: any) => { + console.log(editorState); + if (handleChange) { - handleChange(getPlainTextFromEditor(props.form.values.example)); + handleChange(editorState); } if (getEditorValue) { getEditorValue(editorState); } + console.log(name, editorState); + props.form.setFieldValue(name, editorState); }; @@ -207,7 +211,13 @@ export const EmojiInput = ({ ); const input = ( - + ); return input; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 6e6ea16fa..a506437dc 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -106,19 +106,6 @@ export const WhatsAppEditor = ({ const [editor] = useLexicalComposerContext(); useEffect(() => { - // const sendMessageCommand = editor.registerCommand( - // KEY_ENTER_COMMAND, - // (event: KeyboardEvent) => { - // // Handle enter key presses here - // console.log('nf'); - - // // sendMessage(getPlainTextFromEditor(editor.getRootElement())); - // return false; - // }, - // COMMAND_PRIORITY_LOW - // ); - - // sendMessageCommand(); return editor.registerCommand( KEY_DOWN_COMMAND, @@ -129,15 +116,6 @@ export const WhatsAppEditor = ({ let formatter = ''; if (event.code === 'Enter' && !readOnly) { event.preventDefault(); // Prevent line break on enter - // editor.update(() => { - // const emptyNode = createEmptyNode(); // Replace with your preferred empty node constructor - // editor.setEditorState( - // editor.createEditorState({ - // nodes: [emptyNode], - // }) - // ); - // }); - // sendMessage(getPlainTextFromEditor(editor.getRootElement())); } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { formatter = 'bold'; } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { diff --git a/src/containers/Form/FormLayout.tsx b/src/containers/Form/FormLayout.tsx index 9cd280ea9..f4fbd415a 100644 --- a/src/containers/Form/FormLayout.tsx +++ b/src/containers/Form/FormLayout.tsx @@ -373,16 +373,24 @@ export const FormLayout = ({ } }; const saveHandler = ({ languageId: languageIdValue, ...itemData }: any) => { + console.log(itemData, defaultAttribute); + let payload = { ...itemData, ...defaultAttribute, }; - payload = languageSupport - ? { ...payload, languageId: Number(languageIdValue) } - : { ...payload }; + + console.log(payload); + + // payload = languageSupport + // ? { ...payload, languageId: Number(languageIdValue) } + // : { ...payload }; + console.log(languageSupport); // create custom payload for searches if (setPayload) { + console.log(payload); + payload = setPayload(payload); if (advanceSearch) { const data = advanceSearch(payload); @@ -527,6 +535,8 @@ export const FormLayout = ({ validationSchema={validationSchema} onSubmit={(itemData, { setErrors }) => { // when you want to show custom error on form field and error message is not coming from api + console.log(itemData); + setCustomError({ setErrors }); saveHandler(itemData); }} @@ -557,6 +567,7 @@ export const FormLayout = ({ color="primary" onClick={() => { onSaveButtonClick(errors); + console.log(errors); submitForm(); }} className={styles.Button} diff --git a/src/containers/InteractiveMessage/InteractiveMessage.helper.ts b/src/containers/InteractiveMessage/InteractiveMessage.helper.ts index fea220abb..3e3219a8f 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.helper.ts +++ b/src/containers/InteractiveMessage/InteractiveMessage.helper.ts @@ -39,7 +39,7 @@ export const validator = (templateType: any, t: any) => { .required(t('Title is required')) .max(60, t('Title can be at most 60 characters')), body: Yup.string() - .transform((_current, original) => original.getCurrentContent().getPlainText()) + // .transform((_current, original) => original.getCurrentContent().getPlainText()) .when('type', { is: (val: any) => val && val.id && val.id === 'DOCUMENT', then: (schema) => schema.nullable(), @@ -239,7 +239,7 @@ export const getVariableOptions = async (setContactVariables: any) => { properties.properties .map((i: any) => contactVariablesprefix.concat(i.key)) .concat(fields) - .map((val: string) => ({ name: val })) + .map((val: string) => val) .slice(1); setContactVariables(contacts); diff --git a/src/containers/InteractiveMessage/InteractiveMessage.tsx b/src/containers/InteractiveMessage/InteractiveMessage.tsx index 713c94e71..bd7c3a83b 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.tsx @@ -60,7 +60,7 @@ export const InteractiveMessage = () => { const navigate = useNavigate(); const [title, setTitle] = useState(''); const [footer, setFooter] = useState(''); - const [body, setBody] = useState(EditorState.createEmpty()); + const [body, setBody] = useState(); const [templateType, setTemplateType] = useState(QUICK_REPLY); const [templateTypeField, setTemplateTypeField] = useState(templateTypeOptions[0]); const [templateButtons, setTemplateButtons] = useState>([{ value: '' }]); diff --git a/src/containers/Template/Editor.module.css b/src/containers/Template/Editor.module.css new file mode 100644 index 000000000..991e15aa2 --- /dev/null +++ b/src/containers/Template/Editor.module.css @@ -0,0 +1,110 @@ +.HelperText { + margin-left: 16px !important; + color: #93a29b !important; + line-height: 1 !important; + font-size: 12px !important; + margin-top: 4px !important; + /* position: absolute; */ + /* bottom: 0; */ +} + +.Editor { + margin-bottom: 1rem; + position: relative; + border: 2px solid rgba(0, 0, 0, 0.23); + border-radius: 12px; + height: 10rem; + position: relative; + padding: 0 1rem; +} + +.EditorInput { + resize: none; + font-size: 16px; + overflow: auto; + width: 100%; + min-height: 40px; + margin-top: 4px; + position: relative; + tab-size: 1; + outline: 0; +} + +.boxii { + background-color: red !important; +} + +.EditorWrapper { + margin-bottom: 0.8rem; +} + +.Multiline { + padding-bottom: 35px !important; +} + +.OutlineInput > div:first-child { + width: inherit !important; + height: 100px; + overflow: auto; +} + +.EmojiPosition { + cursor: pointer; + position: absolute; + bottom: 20px; + right: 20px; + white-space: initial !important; +} + +.Emoji { + width: 24px; +} + +.Font { + line-height: 1.25; + font-weight: 400; + font-size: 16px; + font-family: 'Heebo', sans-serif; + color: #073f24; + text-transform: inherit !important; +} + +/* + Overriding draft-js mentions styles as per requirement +*/ +.mentionSuggestions { + composes: Font; + background: #fff; + border-radius: 8px; + cursor: pointer; + display: flex; + flex-direction: column; + box-sizing: border-box; + transform-origin: 50% 0%; + transform: scaleY(0); + box-shadow: 0px 6px 6px 0px lightgray; + z-index: 100; + overflow-y: auto; + max-height: 360px; +} + +.mentionSuggestionsEntry { + padding: 7px 10px 3px 10px; + transition: background-color 0.4s cubic-bezier(0.27, 1.27, 0.48, 0.56); +} + +.mentionSuggestionsEntry:active { + background-color: #edf6f2; +} + +.mentionSuggestionsEntryFocused { + composes: mentionSuggestionsEntry; + background-color: #edf6f2; +} + +.mentionSuggestionsEntryText, +.mentionSuggestionsEntryTitle { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx new file mode 100644 index 000000000..f075b99e5 --- /dev/null +++ b/src/containers/Template/Editor.tsx @@ -0,0 +1,283 @@ +import styles from './Editor.module.css'; +import { forwardRef, useCallback, useState } from 'react'; +import { useEffect } from 'react'; + +import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; +import { ContentEditable } from '@lexical/react/LexicalContentEditable'; +import { $getSelection, $createTextNode, $getRoot } from 'lexical'; +import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; +import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; +import { useResizeDetector } from 'react-resize-detector'; +import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; +import { useTranslation } from 'react-i18next'; +import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW, $isRangeSelection, createCommand } from 'lexical'; +import styled from '@emotion/styled'; +import { + ClickAwayListener, + FormHelperText, + IconButton, + InputAdornment, + OutlinedInput, +} from '@mui/material'; +import { Input } from 'components/UI/Form/Input/Input'; +import { + BeautifulMentionsPlugin, + BeautifulMentionNode, + BeautifulMentionsMenuProps, + BeautifulMentionsTheme, + BeautifulMentionsMenuItemProps, + BeautifulMentionComponentProps, + createBeautifulMentionNode, +} from 'lexical-beautiful-mentions'; +import Picker from '@emoji-mart/react'; +import data from '@emoji-mart/data'; + +export interface EditorProps { + type?: any; + field: { name: string; onChange?: any; value: any; onBlur: any }; + disabled?: any; + editor?: any; + label: string; + form?: { touched: any; errors: any }; + placeholder: any; + rows?: number; + helperText?: any; + picker?: any; + textArea?: boolean; + togglePassword?: boolean; + endAdornmentCallback?: any; + validate?: any; + endAdornment?: any; + inputProp?: any; + translation?: string; + onChange?: any; +} + +export const Editor = ({ textArea = false, disabled = false, ...props }: EditorProps) => { + const { + field, + form, + helperText, + type, + togglePassword, + endAdornmentCallback, + picker, + placeholder, + editor, + rows, + endAdornment, + inputProp, + translation, + onChange, + } = props; + const onResize = useCallback((height: any) => { + // handleHeightChange(height - 40); + }, []); + + // const { getEditorValue } = props; + const onError = (error: any) => { + console.error(error); + }; + + const beautifulMentionsTheme: BeautifulMentionsTheme = { + // 👇 use the trigger name as the key + '@': 'px-1 mx-px ...', + // 👇 add the "Focused" suffix to style the focused mention + '@Focused': 'outline-none shadow-md ...', + // 👇 use a configuration object if you need to apply different styles to trigger and value + 'due:': { + trigger: 'text-blue-400 ...', + value: 'text-orange-400 ...', + }, + }; + const exampleTheme = { + ltr: 'ltr', + rtl: 'rtl', + paragraph: 'editor-paragraph', + input: 'editor-input', + beautifulMentions: beautifulMentionsTheme, + }; + const value = + '{"root":{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1}],"direction":null,"format":"","indent":0,"type":"root","version":1}}'; + + const CustomMentionComponent = forwardRef( + ({ trigger, value, data: myData, children, ...other }, ref) => { + return ( +
+ {value} +
+ ); + } + ); + + const initialConfig = { + namespace: 'MyEditor', + onError, + theme: exampleTheme, + paragraph: 'editor-paragraph', + input: 'editor-input', + nodes: [...createBeautifulMentionNode(CustomMentionComponent)], + }; + + const mentions = props.inputProp?.suggestions || []; + + const suggestions = { + '@': mentions, + }; + + console.log(mentions); + + const { ref } = useResizeDetector({ + refreshMode: 'debounce', + refreshRate: 1000, + onResize, + }); + function Placeholder() { + return ''; + } + const handleFormatting = (text: string, formatter: string) => { + switch (formatter) { + case 'bold': + return `*${text}*`; + case 'italic': + return `_${text}_`; + case 'strikethrough': + return `~${text}~`; + default: + return text; + } + }; + function MyCustomAutoFocusPlugin() { + const [editor] = useLexicalComposerContext(); + + useEffect(() => { + return editor.registerCommand( + KEY_DOWN_COMMAND, + (event: KeyboardEvent) => { + // Handle event here + let formatter = ''; + if (event.code === 'Enter') { + event.preventDefault(); // Prevent line break on enter + } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { + formatter = 'bold'; + } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { + formatter = 'italic'; + } + + editor.update(() => { + const selection = $getSelection(); + if (selection?.getTextContent() && formatter) { + const text = handleFormatting(selection?.getTextContent(), formatter); + const newNode = $createTextNode(text); + selection?.insertNodes([newNode]); + } + }); + return false; + }, + COMMAND_PRIORITY_LOW + ); + }, [editor]); + + return null; + } + + const MuiContentEditable = styled(ContentEditable)({ + minHeight: '150px', + outline: 'none', + width: '100%', + position: 'relative', + borderRadius: '8px', + paddingRight: '14px', + padding: '2px 14px', + fontWeight: '400', + border: '1px solid rgba(0, 0, 0, 0.23)', + }); + + const [showEmojiPicker, setShowEmojiPicker] = useState(false); + + const ADD_EMOJI_COMMAND = createCommand(); + const AddEmojiPlugin = () => { + const [editor] = useLexicalComposerContext(); + + useEffect(() => { + return editor.registerCommand( + ADD_EMOJI_COMMAND, + (payload: string) => { + const selection = $getSelection(); + if ($isRangeSelection(selection)) { + selection.insertNodes([$createTextNode(payload)]); + } + return true; + }, + 1 + ); + }, [editor]); + return ( + { + setShowEmojiPicker(false); + }} + > + + setShowEmojiPicker(!showEmojiPicker)} + > + + 😀 + + + + {showEmojiPicker && ( + { + editor.dispatchCommand(ADD_EMOJI_COMMAND, d.native); + }} + /> + )} + + + ); + }; + + function onChangee(editorState: any) { + editorState.read(() => { + const root = $getRoot(); + console.log(root.getTextContent()); + + onChange(root.getTextContent()); + }); + } + + return ( +
+
+ + } + contentEditable={} + ErrorBoundary={LexicalErrorBoundary} + /> + + + + + {picker && } + +
+ {props.helperText && ( + {props.helperText} + )} +
+ ); +}; diff --git a/src/containers/Template/Form/HSM/HSM.tsx b/src/containers/Template/Form/HSM/HSM.tsx index c4cd7e7b5..46058cab8 100644 --- a/src/containers/Template/Form/HSM/HSM.tsx +++ b/src/containers/Template/Form/HSM/HSM.tsx @@ -28,7 +28,7 @@ export const HSM = () => { }); const [shortcode, setShortcode] = useState(''); - const [example, setExample] = useState(EditorState.createEmpty()); + const [example, setExample] = useState(); const [category, setCategory] = useState({ label: '', id: '' }); const { t } = useTranslation(); const params = useParams(); @@ -68,6 +68,8 @@ export const HSM = () => { }; const getSimulatorMessage = (messages: any) => { + console.log(messages); + const message = removeFirstLineBreak(messages); const media: any = { ...sampleMessages.media }; const text = getTemplate(message); @@ -93,6 +95,7 @@ export const HSM = () => { if (params.id && !isCopyState) { disabled = true; } + console.log(example); const formFields = [ { @@ -107,6 +110,8 @@ export const HSM = () => { 'Replace variables eg. {{1}} with actual values enclosed in [ ] eg. [12345] to show a complete message with meaningful word/statement/numbers/ special characters.', handleChange: getSimulatorMessage, getEditorValue: (value: any) => { + console.log(value); + setExample(value); }, }, diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index d6de5992f..a01103d03 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -29,12 +29,13 @@ import Loading from 'components/UI/Layout/Loading/Loading'; import { CreateAutoComplete } from 'components/UI/Form/CreateAutoComplete/CreateAutoComplete'; import { validateMedia } from 'common/utils'; import styles from './Template.module.css'; +import { Editor } from '../Editor'; const regexForShortcode = /^[a-z0-9_]+$/g; const HSMValidation = { example: Yup.string() - .transform((_current, original) => original.getCurrentContent().getPlainText()) + // .transform((_current, original) => original.getCurrentContent().getPlainText()) .max(1024, 'Maximum 1024 characters are allowed') .when('body', ([body], schema: any) => schema.test({ @@ -178,8 +179,9 @@ const Template = ({ const [tagId, setTagId] = useState(null); const [label, setLabel] = useState(''); - const [body, setBody] = useState(EditorState.createEmpty()); - const [example, setExample] = useState(EditorState.createEmpty()); + const [body, setBody] = useState(); + const [bodyy, setBodyy] = useState(); + const [example, setExample] = useState(); const [shortcode, setShortcode] = useState(''); const [language, setLanguageId] = useState({}); const [type, setType] = useState(null); @@ -284,7 +286,8 @@ const Template = ({ setIsActive(isActiveValue); if (typeof bodyValue === 'string') { - setBody(getEditorFromContent(bodyValue)); + console.log(bodyValue); + setBody(bodyValue); } if (exampleValue) { @@ -303,7 +306,7 @@ const Template = ({ } const editorStateBody = getEditorFromContent(exampleValue); - setExample(editorStateBody); + // setExample(editorStateBody); onExampleChange(exampleBody); } @@ -325,7 +328,9 @@ const Template = ({ ) { const content = translationsCopy[currentLanguage]; setLabel(content.label); - setBody(getEditorFromContent(content.body)); + console.log(content); + + setBody(content.body); } setTranslations(translationsValue); } @@ -359,7 +364,9 @@ const Template = ({ setLabel(labelValue); if (typeof bodyValue === 'string') { - setBody(getEditorFromContent(bodyValue)); + console.log(bodyValue); + + setBody(bodyValue); } if (typeValue && typeValue !== 'TEXT') { @@ -435,7 +442,7 @@ const Template = ({ const getTemplateAndButton = (text: string) => { const exp = /(\|\s\[)|(\|\[)/; - const areButtonsPresent = text.search(exp); + const areButtonsPresent = -1; let message: any = text; let buttons: any = null; @@ -687,10 +694,12 @@ const Template = ({ ? 'You can also use variable and interactive actions. Variable format: {{1}}, Button format: [Button text,Value] Value can be a URL or a phone number.' : null, getEditorValue: (value: any) => { + console.log(value); setBody(value); }, }, ]; + console.log(body); const handeInputChange = (event: any, row: any, index: any, eventType: any) => { const { value } = event.target; @@ -790,6 +799,7 @@ const Template = ({ const setPayload = (payload: any) => { let payloadCopy = payload; let translationsCopy: any = {}; + console.log(payload); if (template) { if (template.sessionTemplate.sessionTemplate.language.id === language.id) { @@ -909,7 +919,7 @@ const Template = ({ language: Yup.object().nullable().required('Language is required.'), label: Yup.string().required(t('Title is required.')).max(50, t('Title length is too long.')), body: Yup.string() - .transform((current, original) => original.getCurrentContent().getPlainText()) + // .transform((current, original) => original.getCurrentContent().getPlainText()) .required(t('Message is required.')) .max(1024, 'Maximum 1024 characters are allowed'), type: Yup.object() From 4f1d4e327ec0d3dd6e9396c72b8481f16b7848c2 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 01:15:05 +0530 Subject: [PATCH 03/36] drafttjs v2 --- src/common/RichEditor.tsx | 3 +- src/components/UI/EmojiPicker/EmojiPicker.tsx | 34 +++++++-- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 64 +++++++--------- .../Chat/ChatMessages/ChatInput/ChatInput.tsx | 65 +++++++++++----- .../Chat/ChatMessages/ChatMessages.tsx | 44 +++++++---- src/containers/Template/Editor.module.css | 50 ++++++++++++- src/containers/Template/Editor.tsx | 74 ++++++++++--------- 7 files changed, 221 insertions(+), 113 deletions(-) diff --git a/src/common/RichEditor.tsx b/src/common/RichEditor.tsx index ef4e43c7a..2c0cfe337 100644 --- a/src/common/RichEditor.tsx +++ b/src/common/RichEditor.tsx @@ -10,6 +10,8 @@ const regexForLink = // Convert Draft.js to WhatsApp message format. export const getPlainTextFromEditor = (editorState: any) => { + console.log(editorState); + return editorState; }; export const getEditorFromContent = (text: string) => @@ -86,7 +88,6 @@ export const WhatsAppToJsx = (text: any) => { export const WhatsAppTemplateButton = (text: string) => { const result: any = { body: text, buttons: null }; - console.log(text); // Returning early if text is null if (!text) return result; diff --git a/src/components/UI/EmojiPicker/EmojiPicker.tsx b/src/components/UI/EmojiPicker/EmojiPicker.tsx index 6e11e9521..ecaf99279 100644 --- a/src/components/UI/EmojiPicker/EmojiPicker.tsx +++ b/src/components/UI/EmojiPicker/EmojiPicker.tsx @@ -1,15 +1,39 @@ import data from '@emoji-mart/data'; import Picker from '@emoji-mart/react'; +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; +import { + $createTextNode, + $getSelection, + $isRangeSelection, + LexicalCommand, + createCommand, +} from 'lexical'; +import { useEffect } from 'react'; export interface EmojiPickerProps { displayStyle: object; onEmojiSelect: Function; } -export const EmojiPicker = ({ displayStyle, onEmojiSelect }: EmojiPickerProps) => ( -
- -
-); +export const EmojiPicker = ({ displayStyle, onEmojiSelect }: EmojiPickerProps) => { + const [editor] = useLexicalComposerContext(); + + return ( +
+ { + console.log(emoji); + editor.update(() => { + const selection = $getSelection(); + if ($isRangeSelection(selection)) { + selection.insertNodes([$createTextNode(emoji.native)]); + } + }); + }} + /> +
+ ); +}; export default EmojiPicker; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index a506437dc..230af6712 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -1,11 +1,10 @@ import { useCallback } from 'react'; import { useEffect } from 'react'; -import { RichUtils, getDefaultKeyBinding, Modifier, EditorState, Editor } from 'draft-js'; -import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { Modifier, EditorState } from 'draft-js'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; -import { $getSelection, $createTextNode } from 'lexical'; +import { $getSelection, $createTextNode, CLEAR_EDITOR_COMMAND, $getRoot } from 'lexical'; import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; @@ -13,12 +12,12 @@ import { useResizeDetector } from 'react-resize-detector'; import { useTranslation } from 'react-i18next'; import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW } from 'lexical'; -import { getPlainTextFromEditor } from 'common/RichEditor'; import styles from './WhatsAppEditor.module.css'; +import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; interface WhatsAppEditorProps { handleHeightChange(newHeight: number): void; - sendMessage(message: string): void; + sendMessage(message: any): void; editorState: any; setEditorState(editorState: any): void; readOnly?: boolean; @@ -68,25 +67,11 @@ export const WhatsAppEditor = ({ onResize, }); - const onError = (error: any) => { - console.error(error); - }; - - const exampleTheme = { - ltr: 'ltr', - rtl: 'rtl', - paragraph: 'editor-paragraph', - input: 'editor-input', - }; - - const initialConfig = { - namespace: 'MyEditor', - onError, - theme: exampleTheme, - }; - const onChange = (editorState: any) => { - setEditorState(editorState.toJSON()); + editorState.read(() => { + const root = $getRoot(); + setEditorState(root.getTextContent()); + }); }; const handleFormatting = (text: string, formatter: string) => { @@ -106,16 +91,22 @@ export const WhatsAppEditor = ({ const [editor] = useLexicalComposerContext(); useEffect(() => { - return editor.registerCommand( KEY_DOWN_COMMAND, (event: KeyboardEvent) => { - console.log(event); - // Handle event here let formatter = ''; if (event.code === 'Enter' && !readOnly) { - event.preventDefault(); // Prevent line break on enter + event.preventDefault(); + + if ( + editor.getRootElement()?.textContent && + typeof editor.getRootElement()?.textContent === 'string' + ) { + sendMessage(editor?.getRootElement()?.textContent); + } + // sendMessage() + // Prevent line break on enter } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { formatter = 'bold'; } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { @@ -148,16 +139,15 @@ export const WhatsAppEditor = ({ return (
- - } - contentEditable={} - ErrorBoundary={LexicalErrorBoundary} - /> - - - + } + contentEditable={} + ErrorBoundary={LexicalErrorBoundary} + /> + + +
); }; diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index e78ab843e..8c15adcaa 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useCallback, useState } from 'react'; import { EditorState, ContentState } from 'draft-js'; import { Container, Button, ClickAwayListener, Fade, IconButton } from '@mui/material'; import { useMutation, useQuery } from '@apollo/client'; @@ -24,6 +24,18 @@ import { AddAttachment } from '../AddAttachment/AddAttachment'; import { VoiceRecorder } from '../VoiceRecorder/VoiceRecorder'; import ChatTemplates from '../ChatTemplates/ChatTemplates'; import styles from './ChatInput.module.css'; +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; +import { + $createParagraphNode, + $createTextNode, + $getRoot, + $getSelection, + $insertNodes, + $isRangeSelection, + LexicalCommand, + TextNode, + createCommand, +} from 'lexical'; export interface ChatInputProps { onSendMessage( @@ -51,7 +63,7 @@ export const ChatInput = ({ isCollection, lastMessageTime, }: ChatInputProps) => { - const [editorState, setEditorState] = useState(EditorState.createEmpty()); + const [editorState, setEditorState] = useState(''); const [selectedTab, setSelectedTab] = useState(''); const [open, setOpen] = useState(false); const [searchVal, setSearchVal] = useState(''); @@ -70,6 +82,8 @@ export const ChatInput = ({ const [showEmojiPicker, setShowEmojiPicker] = useState(false); const { t } = useTranslation(); + const [editor] = useLexicalComposerContext(); + const speedSends = 'Speed sends'; const templates = 'Templates'; const interactiveMsg = 'Interactive msg'; @@ -79,10 +93,16 @@ export const ChatInput = ({ const resetVariable = () => { setUpdatedEditorState(undefined); - setEditorState(EditorState.createEmpty()); + setEditorState(''); setSelectedTemplate(undefined); setInteractiveMessageContent({}); setVariableParam([]); + + // clear the editor state + editor.update(() => { + $getRoot().clear(); + }); + editor.focus(); }; const { data: permission } = useQuery(GET_ATTACHMENT_PERMISSION); @@ -149,7 +169,6 @@ export const ChatInput = ({ }; setUploading(true); } - console.log(message); // check for an empty message or message with just spaces if ((!message || /^\s*$/.test(message)) && !attachmentAdded) return; @@ -178,17 +197,16 @@ export const ChatInput = ({ resetVariable(); // else the type will by default be text } else { - console.log('n'); - onSendMessage(message, null, 'TEXT', selectedTemplate, variableParam); resetVariable(); } // Resetting the EditorState - // setEditorState(''); - // EditorState.moveFocusToEnd( - // EditorState.push(editorState, ContentState.createFromText(''), 'remove-range') - // ) + setEditorState( + EditorState.moveFocusToEnd( + EditorState.push(editorState, ContentState.createFromText(''), 'remove-range') + ) + ); }; const emojiStyles = { @@ -226,6 +244,7 @@ export const ChatInput = ({ const handleSelectText = (obj: any, isInteractiveMsg: boolean = false) => { resetVariable(); + console.log(obj.body); // set selected template @@ -234,11 +253,19 @@ export const ChatInput = ({ const interactiveContent = JSON.parse(obj.interactiveContent); messageBody = getInteractiveMessageBody(interactiveContent); setInteractiveMessageContent(interactiveContent); + console.log(interactiveContent); } setSelectedTemplate(obj); // Conversion from HTML text to EditorState setEditorState(getEditorFromContent(messageBody)); + editor.update(() => { + const root = $getRoot(); + const paragraph = $createParagraphNode(); + paragraph.append($createTextNode(messageBody || '')); + root.append(paragraph); + }); + console.log(getEditorFromContent(messageBody)); // Add attachment if present if (Object.prototype.hasOwnProperty.call(obj, 'MessageMedia') && obj.MessageMedia) { @@ -264,7 +291,13 @@ export const ChatInput = ({ }; const updateEditorState = (body: string) => { - setUpdatedEditorState(body); + editor.update(() => { + const root = $getRoot(); + root.clear(); + const paragraph = $createParagraphNode(); + paragraph.append($createTextNode(body)); + root.append(paragraph); + }); }; const variableParams = (params: Array) => { @@ -372,6 +405,7 @@ export const ChatInput = ({ }; dialog = ; } + return ( {showEmojiPicker ? ( - - setEditorState(updatedValue(emoji, editorState, true)) - } - displayStyle={emojiStyles} - /> + {}} displayStyle={emojiStyles} /> ) : null} @@ -492,7 +521,7 @@ export const ChatInput = ({ submitMessage(getPlainTextFromEditor(editorState)); } }} - // disabled={(!attachmentAdded && !recordedAudio) || uploading} + disabled={(!attachmentAdded && !recordedAudio) || uploading} > diff --git a/src/containers/Chat/ChatMessages/ChatMessages.tsx b/src/containers/Chat/ChatMessages/ChatMessages.tsx index 39b4c69f0..09c883b3e 100644 --- a/src/containers/Chat/ChatMessages/ChatMessages.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessages.tsx @@ -28,6 +28,7 @@ import { import { getCachedConverations, updateConversationsCache } from '../../../services/ChatService'; import { addLogs, getDisplayName, isSimulator } from '../../../common/utils'; import { CollectionInformation } from '../../Collection/CollectionInformation/CollectionInformation'; +import { LexicalComposer } from '@lexical/react/LexicalComposer'; export interface ChatMessagesProps { contactId?: number | string | null; @@ -511,10 +512,7 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe const showDaySeparator = (currentDate: string, nextDate: string) => { // if it's last message and its date is greater than current date then show day separator - if ( - !nextDate && - dayjs(currentDate).format(ISO_DATE_FORMAT) < dayjs().format(ISO_DATE_FORMAT) - ) { + if (!nextDate && dayjs(currentDate).format(ISO_DATE_FORMAT) < dayjs().format(ISO_DATE_FORMAT)) { return true; } @@ -670,13 +668,20 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe ); chatInputSection = ( - + console.log(error), + }} + > + + ); } else if (collectionId && conversationInfo.group) { topChatBar = ( @@ -688,11 +693,18 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe ); chatInputSection = ( - + console.log(error), + }} + > + + ); } diff --git a/src/containers/Template/Editor.module.css b/src/containers/Template/Editor.module.css index 991e15aa2..50b496f2d 100644 --- a/src/containers/Template/Editor.module.css +++ b/src/containers/Template/Editor.module.css @@ -9,13 +9,28 @@ } .Editor { - margin-bottom: 1rem; + /* margin-bottom: 1rem; */ position: relative; border: 2px solid rgba(0, 0, 0, 0.23); border-radius: 12px; height: 10rem; position: relative; padding: 0 1rem; + position: relative; + display: block; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; +} + +.Label { + font-size: 16px; + font-weight: 500; + color: #93a29b !important; +} + +.DangerText { + margin-left: 16px !important; + color: #fb5c5c; } .EditorInput { @@ -24,6 +39,7 @@ overflow: auto; width: 100%; min-height: 40px; + height: 100%; margin-top: 4px; position: relative; tab-size: 1; @@ -35,7 +51,7 @@ } .EditorWrapper { - margin-bottom: 0.8rem; + margin: 1rem 0; } .Multiline { @@ -56,6 +72,36 @@ white-space: initial !important; } +.editorScroller { + min-height: 150px; + border: 0; + display: flex; + position: relative; + outline: 0; + z-index: 0; +} + +.disabled { + position: relative; + border: 2px solid rgba(0, 0, 0, 0.23); + border-radius: 12px; + height: 10rem; + position: relative; + padding: 0 1rem; + position: relative; + display: block; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; + color: rgba(0, 0, 0, 0.38); + pointer-events: none; +} +.editor { + flex: auto; + position: relative; + resize: vertical; + z-index: -1; +} + .Emoji { width: 24px; } diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index f075b99e5..214eee76e 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -5,7 +5,7 @@ import { useEffect } from 'react'; import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; -import { $getSelection, $createTextNode, $getRoot } from 'lexical'; +import { $getSelection, $createTextNode, $getRoot, $createParagraphNode } from 'lexical'; import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; @@ -14,20 +14,9 @@ import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; import { useTranslation } from 'react-i18next'; import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW, $isRangeSelection, createCommand } from 'lexical'; import styled from '@emotion/styled'; -import { - ClickAwayListener, - FormHelperText, - IconButton, - InputAdornment, - OutlinedInput, -} from '@mui/material'; -import { Input } from 'components/UI/Form/Input/Input'; +import { ClickAwayListener, FormHelperText, IconButton, InputAdornment } from '@mui/material'; import { BeautifulMentionsPlugin, - BeautifulMentionNode, - BeautifulMentionsMenuProps, - BeautifulMentionsTheme, - BeautifulMentionsMenuItemProps, BeautifulMentionComponentProps, createBeautifulMentionNode, } from 'lexical-beautiful-mentions'; @@ -81,26 +70,20 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP console.error(error); }; - const beautifulMentionsTheme: BeautifulMentionsTheme = { - // 👇 use the trigger name as the key - '@': 'px-1 mx-px ...', - // 👇 add the "Focused" suffix to style the focused mention - '@Focused': 'outline-none shadow-md ...', - // 👇 use a configuration object if you need to apply different styles to trigger and value - 'due:': { - trigger: 'text-blue-400 ...', - value: 'text-orange-400 ...', - }, - }; + function prepopulatedRichText() { + const root = $getRoot(); + const paragraph = $createParagraphNode(); + paragraph.append($createTextNode(field?.value || '')); + console.log(paragraph); + root.append(paragraph); + } + const exampleTheme = { ltr: 'ltr', rtl: 'rtl', paragraph: 'editor-paragraph', input: 'editor-input', - beautifulMentions: beautifulMentionsTheme, }; - const value = - '{"root":{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1}],"direction":null,"format":"","indent":0,"type":"root","version":1}}'; const CustomMentionComponent = forwardRef( ({ trigger, value, data: myData, children, ...other }, ref) => { @@ -111,14 +94,16 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP ); } ); + console.log(field.value); const initialConfig = { namespace: 'MyEditor', onError, theme: exampleTheme, - paragraph: 'editor-paragraph', - input: 'editor-input', - nodes: [...createBeautifulMentionNode(CustomMentionComponent)], + // paragraph: 'editor-paragraph', + // input: 'editor-input', + // nodes: [...createBeautifulMentionNode(CustomMentionComponent)], + editorState: prepopulatedRichText, }; const mentions = props.inputProp?.suggestions || []; @@ -127,8 +112,6 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP '@': mentions, }; - console.log(mentions); - const { ref } = useResizeDetector({ refreshMode: 'debounce', refreshRate: 1000, @@ -149,9 +132,20 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP return text; } }; + function MyCustomAutoFocusPlugin() { const [editor] = useLexicalComposerContext(); + useEffect(() => { + editor.update(() => { + const root = $getRoot(); + const paragraph = $createParagraphNode(); + paragraph.append($createTextNode(field?.value || '')); + console.log(paragraph); + root.append(paragraph); + }); + }, [field.value]); + useEffect(() => { return editor.registerCommand( KEY_DOWN_COMMAND, @@ -214,6 +208,7 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP 1 ); }, [editor]); + return ( { @@ -250,6 +245,8 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP }; function onChangee(editorState: any) { + console.log('triggered'); + editorState.read(() => { const root = $getRoot(); console.log(root.getTextContent()); @@ -260,12 +257,18 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP return (
-
+
} - contentEditable={} + contentEditable={ +
+
+ +
+
+ } ErrorBoundary={LexicalErrorBoundary} /> @@ -275,6 +278,9 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP {picker && }
+ {form && form.errors[field.name] && form.touched[field.name] ? ( + {form.errors[field.name]} + ) : null} {props.helperText && ( {props.helperText} )} From 63ea01edd33b40d6d09185d08fa0cb02c2c3a30f Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 03:09:06 +0530 Subject: [PATCH 04/36] draftjs wrapping up v1 --- src/common/RichEditor.tsx | 2 - src/components/UI/EmojiPicker/EmojiPicker.tsx | 1 - .../UI/Form/EmojiInput/EmojiInput.tsx | 23 +- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 9 - .../Chat/ChatMessages/ChatInput/ChatInput.tsx | 24 +- src/containers/Form/FormLayout.tsx | 15 +- src/containers/Template/Editor.module.css | 113 ++++++++ src/containers/Template/Editor.tsx | 271 ++++++------------ src/containers/Template/Form/HSM/HSM.tsx | 5 - src/containers/Template/Form/Template.tsx | 18 +- 10 files changed, 232 insertions(+), 249 deletions(-) diff --git a/src/common/RichEditor.tsx b/src/common/RichEditor.tsx index 2c0cfe337..4fe3b344f 100644 --- a/src/common/RichEditor.tsx +++ b/src/common/RichEditor.tsx @@ -10,8 +10,6 @@ const regexForLink = // Convert Draft.js to WhatsApp message format. export const getPlainTextFromEditor = (editorState: any) => { - console.log(editorState); - return editorState; }; export const getEditorFromContent = (text: string) => diff --git a/src/components/UI/EmojiPicker/EmojiPicker.tsx b/src/components/UI/EmojiPicker/EmojiPicker.tsx index ecaf99279..6b4914f9b 100644 --- a/src/components/UI/EmojiPicker/EmojiPicker.tsx +++ b/src/components/UI/EmojiPicker/EmojiPicker.tsx @@ -23,7 +23,6 @@ export const EmojiPicker = ({ displayStyle, onEmojiSelect }: EmojiPickerProps) = { - console.log(emoji); editor.update(() => { const selection = $getSelection(); if ($isRangeSelection(selection)) { diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index 7e3737bee..1caa84cfa 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -3,11 +3,11 @@ import { RichUtils, Modifier, EditorState, ContentState } from 'draft-js'; import createMentionPlugin from '@draft-js-plugins/mention'; import { InputAdornment, IconButton, ClickAwayListener } from '@mui/material'; -import { getPlainTextFromEditor } from 'common/RichEditor'; import { EmojiPicker } from 'components/UI/EmojiPicker/EmojiPicker'; -import { Input } from '../Input/Input'; import { Editor } from 'containers/Template/Editor'; import Styles from './EmojiInput.module.css'; +import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { BeautifulMentionNode } from 'lexical-beautiful-mentions'; export interface EmojiInputProps { field: any; @@ -122,15 +122,12 @@ export const EmojiInput = ({ }; const draftJsChange = (editorState: any) => { - console.log(editorState); - if (handleChange) { handleChange(editorState); } if (getEditorValue) { getEditorValue(editorState); } - console.log(name, editorState); props.form.setFieldValue(name, editorState); }; @@ -211,13 +208,15 @@ export const EmojiInput = ({ ); const input = ( - + console.log(error), + nodes: [BeautifulMentionNode], + }} + > + + ); return input; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 230af6712..d74664fee 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -18,7 +18,6 @@ import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; interface WhatsAppEditorProps { handleHeightChange(newHeight: number): void; sendMessage(message: any): void; - editorState: any; setEditorState(editorState: any): void; readOnly?: boolean; } @@ -47,16 +46,11 @@ export const updatedValue = (input: any, editorState: EditorState, isEmoji: bool export const WhatsAppEditor = ({ setEditorState, sendMessage, - editorState, handleHeightChange, readOnly = false, }: WhatsAppEditorProps) => { const { t } = useTranslation(); - const handleChange = (editorStateChange: any) => { - setEditorState(editorStateChange); - }; - const onResize = useCallback((height: any) => { handleHeightChange(height - 40); }, []); @@ -113,8 +107,6 @@ export const WhatsAppEditor = ({ formatter = 'italic'; } - // console.log(formatter); - editor.update(() => { const selection = $getSelection(); if (selection?.getTextContent() && formatter) { @@ -123,7 +115,6 @@ export const WhatsAppEditor = ({ selection?.insertNodes([newNode]); } }); - // console.log(event); return false; }, diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index 8c15adcaa..92f10ae14 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -202,11 +202,11 @@ export const ChatInput = ({ } // Resetting the EditorState - setEditorState( - EditorState.moveFocusToEnd( - EditorState.push(editorState, ContentState.createFromText(''), 'remove-range') - ) - ); + editor.update(() => { + const root = $getRoot(); + root.clear(); + }); + editor.focus(); }; const emojiStyles = { @@ -244,8 +244,6 @@ export const ChatInput = ({ const handleSelectText = (obj: any, isInteractiveMsg: boolean = false) => { resetVariable(); - console.log(obj.body); - // set selected template let messageBody = obj.body; @@ -253,7 +251,6 @@ export const ChatInput = ({ const interactiveContent = JSON.parse(obj.interactiveContent); messageBody = getInteractiveMessageBody(interactiveContent); setInteractiveMessageContent(interactiveContent); - console.log(interactiveContent); } setSelectedTemplate(obj); @@ -265,7 +262,6 @@ export const ChatInput = ({ paragraph.append($createTextNode(messageBody || '')); root.append(paragraph); }); - console.log(getEditorFromContent(messageBody)); // Add attachment if present if (Object.prototype.hasOwnProperty.call(obj, 'MessageMedia') && obj.MessageMedia) { @@ -291,6 +287,7 @@ export const ChatInput = ({ }; const updateEditorState = (body: string) => { + setUpdatedEditorState(true); editor.update(() => { const root = $getRoot(); root.clear(); @@ -442,7 +439,6 @@ export const ChatInput = ({ }`} > { - if (updatedEditorState) { - submitMessage(updatedEditorState); - } else { - submitMessage(getPlainTextFromEditor(editorState)); - } + submitMessage(editorState); }} - disabled={(!attachmentAdded && !recordedAudio) || uploading} + // disabled={(!attachmentAdded && !recordedAudio) || uploading} > diff --git a/src/containers/Form/FormLayout.tsx b/src/containers/Form/FormLayout.tsx index f4fbd415a..6d7723c08 100644 --- a/src/containers/Form/FormLayout.tsx +++ b/src/containers/Form/FormLayout.tsx @@ -373,24 +373,17 @@ export const FormLayout = ({ } }; const saveHandler = ({ languageId: languageIdValue, ...itemData }: any) => { - console.log(itemData, defaultAttribute); - let payload = { ...itemData, ...defaultAttribute, }; - console.log(payload); - - // payload = languageSupport - // ? { ...payload, languageId: Number(languageIdValue) } - // : { ...payload }; - console.log(languageSupport); + payload = languageSupport + ? { ...payload, languageId: Number(languageIdValue) } + : { ...payload }; // create custom payload for searches if (setPayload) { - console.log(payload); - payload = setPayload(payload); if (advanceSearch) { const data = advanceSearch(payload); @@ -535,7 +528,6 @@ export const FormLayout = ({ validationSchema={validationSchema} onSubmit={(itemData, { setErrors }) => { // when you want to show custom error on form field and error message is not coming from api - console.log(itemData); setCustomError({ setErrors }); saveHandler(itemData); @@ -567,7 +559,6 @@ export const FormLayout = ({ color="primary" onClick={() => { onSaveButtonClick(errors); - console.log(errors); submitForm(); }} className={styles.Button} diff --git a/src/containers/Template/Editor.module.css b/src/containers/Template/Editor.module.css index 50b496f2d..9b0644d56 100644 --- a/src/containers/Template/Editor.module.css +++ b/src/containers/Template/Editor.module.css @@ -154,3 +154,116 @@ overflow: hidden; text-overflow: ellipsis; } + +.editorPlaceholder { + color: #999; + overflow: hidden; + position: absolute; + text-overflow: ellipsis; + top: 1px; + left: 14px; + font-size: 16px; + user-select: none; + display: inline-block; + pointer-events: none; +} + +/* .MentionMenu { + background: #fff; + box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.3); + border-radius: 8px; + position: fixed; +} */ + +.MentionMenu { + padding: 0; + background: #fff; + box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.3); + border-radius: 8px; + position: fixed; + list-style: none; + margin: 0; + border-radius: 8px; + max-height: 200px; + overflow-y: scroll; +} + +.MentionMenu { + -ms-overflow-style: none; + scrollbar-width: none; +} + +.MentionMenu ul li { + margin: 0; + min-width: 180px; + font-size: 14px; + outline: none; + cursor: pointer; + border-radius: 8px; +} + +.MentionMenu ul li.selected { + background: #eee; +} + +.MentionMenu li { + /* margin: 0 8px 0 8px; */ + padding: 8px; + color: #050505; + cursor: pointer; + line-height: 16px; + font-size: 15px; + display: flex; + align-content: center; + flex-direction: row; + flex-shrink: 0; + background-color: #fff; + border-radius: 8px; + border: 0; +} + +.MentionMenu li.active { + display: flex; + width: 20px; + height: 20px; + background-size: contain; +} + +.MentionMenu li:first-child { + border-radius: 8px 8px 0px 0px; +} + +.MentionMenu li:last-child { + border-radius: 0px 0px 8px 8px; +} + +.MentionMenu li:hover { + background-color: #eee; +} + +.MentionMenu li .text { + display: flex; + line-height: 20px; + flex-grow: 1; + min-width: 150px; +} + +.MentionMenu li .icon { + display: flex; + /* width: 20px; */ + /* height: 20px; */ + user-select: none; + margin-right: 8px; + line-height: 16px; + background-size: contain; + background-repeat: no-repeat; + background-position: center; +} + +.component-picker-menu { + width: 200px; +} + +.mentions-menu { + width: 250px; +} diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index 214eee76e..f117fd680 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -1,8 +1,6 @@ import styles from './Editor.module.css'; import { forwardRef, useCallback, useState } from 'react'; import { useEffect } from 'react'; - -import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; import { $getSelection, $createTextNode, $getRoot, $createParagraphNode } from 'lexical'; @@ -11,23 +9,19 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; import { useResizeDetector } from 'react-resize-detector'; import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; -import { useTranslation } from 'react-i18next'; -import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW, $isRangeSelection, createCommand } from 'lexical'; -import styled from '@emotion/styled'; +import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW, createCommand } from 'lexical'; import { ClickAwayListener, FormHelperText, IconButton, InputAdornment } from '@mui/material'; import { BeautifulMentionsPlugin, - BeautifulMentionComponentProps, - createBeautifulMentionNode, + BeautifulMentionsMenuProps, + BeautifulMentionsMenuItemProps, } from 'lexical-beautiful-mentions'; -import Picker from '@emoji-mart/react'; -import data from '@emoji-mart/data'; +import EmojiPicker from 'components/UI/EmojiPicker/EmojiPicker'; export interface EditorProps { type?: any; field: { name: string; onChange?: any; value: any; onBlur: any }; disabled?: any; - editor?: any; label: string; form?: { touched: any; errors: any }; placeholder: any; @@ -44,82 +38,40 @@ export interface EditorProps { onChange?: any; } -export const Editor = ({ textArea = false, disabled = false, ...props }: EditorProps) => { - const { - field, - form, - helperText, - type, - togglePassword, - endAdornmentCallback, - picker, - placeholder, - editor, - rows, - endAdornment, - inputProp, - translation, - onChange, - } = props; - const onResize = useCallback((height: any) => { - // handleHeightChange(height - 40); - }, []); - - // const { getEditorValue } = props; - const onError = (error: any) => { - console.error(error); - }; - - function prepopulatedRichText() { - const root = $getRoot(); - const paragraph = $createParagraphNode(); - paragraph.append($createTextNode(field?.value || '')); - console.log(paragraph); - root.append(paragraph); - } - - const exampleTheme = { - ltr: 'ltr', - rtl: 'rtl', - paragraph: 'editor-paragraph', - input: 'editor-input', - }; - - const CustomMentionComponent = forwardRef( - ({ trigger, value, data: myData, children, ...other }, ref) => { - return ( -
- {value} -
- ); - } - ); - console.log(field.value); +type MentionsProps = { + mentions: any; +}; - const initialConfig = { - namespace: 'MyEditor', - onError, - theme: exampleTheme, - // paragraph: 'editor-paragraph', - // input: 'editor-input', - // nodes: [...createBeautifulMentionNode(CustomMentionComponent)], - editorState: prepopulatedRichText, - }; +export const Editor = ({ textArea = false, disabled = false, ...props }: EditorProps) => { + const { field, form, picker, placeholder, onChange } = props; + const [showEmojiPicker, setShowEmojiPicker] = useState(false); const mentions = props.inputProp?.suggestions || []; - const suggestions = { - '@': mentions, + '@': mentions?.map((el: any) => el?.split('@')[1]), }; + const [editor] = useLexicalComposerContext(); + const { ref } = useResizeDetector({ refreshMode: 'debounce', refreshRate: 1000, - onResize, }); - function Placeholder() { - return ''; - } + + const Placeholder = () => { + return

{placeholder}

; + }; + + useEffect(() => { + editor.update(() => { + const root = $getRoot(); + root.clear(); + const paragraph = $createParagraphNode(); + paragraph.append($createTextNode(field.value || '')); + root.append(paragraph); + }); + }, []); + const handleFormatting = (text: string, formatter: string) => { switch (formatter) { case 'bold': @@ -133,19 +85,9 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP } }; - function MyCustomAutoFocusPlugin() { + const MyCustomAutoFocusPlugin = () => { const [editor] = useLexicalComposerContext(); - useEffect(() => { - editor.update(() => { - const root = $getRoot(); - const paragraph = $createParagraphNode(); - paragraph.append($createTextNode(field?.value || '')); - console.log(paragraph); - root.append(paragraph); - }); - }, [field.value]); - useEffect(() => { return editor.registerCommand( KEY_DOWN_COMMAND, @@ -175,108 +117,73 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP }, [editor]); return null; - } - - const MuiContentEditable = styled(ContentEditable)({ - minHeight: '150px', - outline: 'none', - width: '100%', - position: 'relative', - borderRadius: '8px', - paddingRight: '14px', - padding: '2px 14px', - fontWeight: '400', - border: '1px solid rgba(0, 0, 0, 0.23)', - }); - - const [showEmojiPicker, setShowEmojiPicker] = useState(false); - - const ADD_EMOJI_COMMAND = createCommand(); - const AddEmojiPlugin = () => { - const [editor] = useLexicalComposerContext(); - - useEffect(() => { - return editor.registerCommand( - ADD_EMOJI_COMMAND, - (payload: string) => { - const selection = $getSelection(); - if ($isRangeSelection(selection)) { - selection.insertNodes([$createTextNode(payload)]); - } - return true; - }, - 1 - ); - }, [editor]); - - return ( - { - setShowEmojiPicker(false); - }} - > - - setShowEmojiPicker(!showEmojiPicker)} - > - - 😀 - - - - {showEmojiPicker && ( - { - editor.dispatchCommand(ADD_EMOJI_COMMAND, d.native); - }} - /> - )} - - - ); }; - function onChangee(editorState: any) { - console.log('triggered'); - + const handleChange = (editorState: any) => { editorState.read(() => { const root = $getRoot(); - console.log(root.getTextContent()); - onChange(root.getTextContent()); }); - } + }; + + const emojiStyles = { + position: 'absolute', + bottom: '60px', + right: '-150px', + zIndex: 100, + }; return (
- - } - contentEditable={ -
-
- -
+ } + contentEditable={ +
+
+
- } - ErrorBoundary={LexicalErrorBoundary} - /> - - - - - {picker && } - +
+ } + ErrorBoundary={LexicalErrorBoundary} + /> + + + + {/* */} + + {picker && ( + { + setShowEmojiPicker(false); + }} + > + + setShowEmojiPicker(!showEmojiPicker)} + > + + 😀 + + + + {showEmojiPicker && ( + {}} displayStyle={emojiStyles} /> + )} + + + )}
{form && form.errors[field.name] && form.touched[field.name] ? ( {form.errors[field.name]} @@ -287,3 +194,11 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP
); }; + +const CustomMenu = forwardRef( + ({ open, loading, ...props }, ref) =>
    +); + +const CustomMenuItem = forwardRef( + ({ selected, item, ...props }, ref) =>
  • +); diff --git a/src/containers/Template/Form/HSM/HSM.tsx b/src/containers/Template/Form/HSM/HSM.tsx index 46058cab8..f56b7655c 100644 --- a/src/containers/Template/Form/HSM/HSM.tsx +++ b/src/containers/Template/Form/HSM/HSM.tsx @@ -68,8 +68,6 @@ export const HSM = () => { }; const getSimulatorMessage = (messages: any) => { - console.log(messages); - const message = removeFirstLineBreak(messages); const media: any = { ...sampleMessages.media }; const text = getTemplate(message); @@ -95,7 +93,6 @@ export const HSM = () => { if (params.id && !isCopyState) { disabled = true; } - console.log(example); const formFields = [ { @@ -110,8 +107,6 @@ export const HSM = () => { 'Replace variables eg. {{1}} with actual values enclosed in [ ] eg. [12345] to show a complete message with meaningful word/statement/numbers/ special characters.', handleChange: getSimulatorMessage, getEditorValue: (value: any) => { - console.log(value); - setExample(value); }, }, diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index a01103d03..8a059f272 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -29,7 +29,6 @@ import Loading from 'components/UI/Layout/Loading/Loading'; import { CreateAutoComplete } from 'components/UI/Form/CreateAutoComplete/CreateAutoComplete'; import { validateMedia } from 'common/utils'; import styles from './Template.module.css'; -import { Editor } from '../Editor'; const regexForShortcode = /^[a-z0-9_]+$/g; @@ -179,9 +178,8 @@ const Template = ({ const [tagId, setTagId] = useState(null); const [label, setLabel] = useState(''); - const [body, setBody] = useState(); - const [bodyy, setBodyy] = useState(); - const [example, setExample] = useState(); + const [body, setBody] = useState(''); + const [example, setExample] = useState(''); const [shortcode, setShortcode] = useState(''); const [language, setLanguageId] = useState({}); const [type, setType] = useState(null); @@ -286,7 +284,6 @@ const Template = ({ setIsActive(isActiveValue); if (typeof bodyValue === 'string') { - console.log(bodyValue); setBody(bodyValue); } @@ -306,7 +303,7 @@ const Template = ({ } const editorStateBody = getEditorFromContent(exampleValue); - // setExample(editorStateBody); + setExample(exampleValue); onExampleChange(exampleBody); } @@ -328,8 +325,6 @@ const Template = ({ ) { const content = translationsCopy[currentLanguage]; setLabel(content.label); - console.log(content); - setBody(content.body); } setTranslations(translationsValue); @@ -364,8 +359,6 @@ const Template = ({ setLabel(labelValue); if (typeof bodyValue === 'string') { - console.log(bodyValue); - setBody(bodyValue); } @@ -442,7 +435,7 @@ const Template = ({ const getTemplateAndButton = (text: string) => { const exp = /(\|\s\[)|(\|\[)/; - const areButtonsPresent = -1; + const areButtonsPresent = text.search(exp); let message: any = text; let buttons: any = null; @@ -694,12 +687,10 @@ const Template = ({ ? 'You can also use variable and interactive actions. Variable format: {{1}}, Button format: [Button text,Value] Value can be a URL or a phone number.' : null, getEditorValue: (value: any) => { - console.log(value); setBody(value); }, }, ]; - console.log(body); const handeInputChange = (event: any, row: any, index: any, eventType: any) => { const { value } = event.target; @@ -799,7 +790,6 @@ const Template = ({ const setPayload = (payload: any) => { let payloadCopy = payload; let translationsCopy: any = {}; - console.log(payload); if (template) { if (template.sessionTemplate.sessionTemplate.language.id === language.id) { From 072e2e3fdfffc45bdafceef5294a24f3a962ace4 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 03:16:36 +0530 Subject: [PATCH 05/36] draftjs wrapping up v1 --- src/components/UI/EmojiPicker/EmojiPicker.tsx | 10 +--------- .../UI/Form/EmojiInput/EmojiInput.tsx | 2 -- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 5 +---- .../Chat/ChatMessages/ChatInput/ChatInput.tsx | 19 ++++--------------- .../InteractiveMessage/InteractiveMessage.tsx | 1 - src/containers/Template/Editor.tsx | 6 +++--- src/containers/Template/Form/HSM/HSM.tsx | 1 - src/containers/Template/Form/Template.tsx | 2 -- 8 files changed, 9 insertions(+), 37 deletions(-) diff --git a/src/components/UI/EmojiPicker/EmojiPicker.tsx b/src/components/UI/EmojiPicker/EmojiPicker.tsx index 6b4914f9b..cf1cc42eb 100644 --- a/src/components/UI/EmojiPicker/EmojiPicker.tsx +++ b/src/components/UI/EmojiPicker/EmojiPicker.tsx @@ -1,15 +1,7 @@ import data from '@emoji-mart/data'; import Picker from '@emoji-mart/react'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; -import { - $createTextNode, - $getSelection, - $isRangeSelection, - LexicalCommand, - createCommand, -} from 'lexical'; -import { useEffect } from 'react'; - +import { $createTextNode, $getSelection, $isRangeSelection } from 'lexical'; export interface EmojiPickerProps { displayStyle: object; onEmojiSelect: Function; diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index 1caa84cfa..a095224dd 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -171,8 +171,6 @@ export const EmojiInput = ({ onChange: draftJsChange, }; - const editor = { inputComponent: DraftField, inputProps }; - const emojiPicker = showEmojiPicker ? ( updateValue(emojiValue, true)} diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index d74664fee..3f70a3313 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -4,12 +4,11 @@ import { useEffect } from 'react'; import { Modifier, EditorState } from 'draft-js'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; -import { $getSelection, $createTextNode, CLEAR_EDITOR_COMMAND, $getRoot } from 'lexical'; +import { $getSelection, $createTextNode, $getRoot } from 'lexical'; import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; import { useResizeDetector } from 'react-resize-detector'; -import { useTranslation } from 'react-i18next'; import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW } from 'lexical'; import styles from './WhatsAppEditor.module.css'; @@ -49,8 +48,6 @@ export const WhatsAppEditor = ({ handleHeightChange, readOnly = false, }: WhatsAppEditorProps) => { - const { t } = useTranslation(); - const onResize = useCallback((height: any) => { handleHeightChange(height - 40); }, []); diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index 92f10ae14..064bd659e 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -1,5 +1,4 @@ -import { useCallback, useState } from 'react'; -import { EditorState, ContentState } from 'draft-js'; +import { useState } from 'react'; import { Container, Button, ClickAwayListener, Fade, IconButton } from '@mui/material'; import { useMutation, useQuery } from '@apollo/client'; import { useTranslation } from 'react-i18next'; @@ -9,10 +8,10 @@ import AttachmentIconSelected from 'assets/images/icons/Attachment/Selected.svg? import VariableIcon from 'assets/images/icons/Template/Variable.svg?react'; import CrossIcon from 'assets/images/icons/Clear.svg?react'; import SendMessageIcon from 'assets/images/icons/SendMessage.svg?react'; -import { getPlainTextFromEditor, getEditorFromContent } from 'common/RichEditor'; +import { getEditorFromContent } from 'common/RichEditor'; import { is24HourWindowOver, pattern } from 'common/constants'; import SearchBar from 'components/UI/SearchBar/SearchBar'; -import WhatsAppEditor, { updatedValue } from 'components/UI/Form/WhatsAppEditor/WhatsAppEditor'; +import WhatsAppEditor from 'components/UI/Form/WhatsAppEditor/WhatsAppEditor'; import Tooltip from 'components/UI/Tooltip/Tooltip'; import { CREATE_MEDIA_MESSAGE, UPLOAD_MEDIA_BLOB } from 'graphql/mutations/Chat'; import { GET_ATTACHMENT_PERMISSION } from 'graphql/queries/Settings'; @@ -25,17 +24,7 @@ import { VoiceRecorder } from '../VoiceRecorder/VoiceRecorder'; import ChatTemplates from '../ChatTemplates/ChatTemplates'; import styles from './ChatInput.module.css'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; -import { - $createParagraphNode, - $createTextNode, - $getRoot, - $getSelection, - $insertNodes, - $isRangeSelection, - LexicalCommand, - TextNode, - createCommand, -} from 'lexical'; +import { $createParagraphNode, $createTextNode, $getRoot } from 'lexical'; export interface ChatInputProps { onSendMessage( diff --git a/src/containers/InteractiveMessage/InteractiveMessage.tsx b/src/containers/InteractiveMessage/InteractiveMessage.tsx index bd7c3a83b..b2044fc78 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.tsx @@ -1,7 +1,6 @@ import { useState, useEffect, useMemo } from 'react'; import * as Yup from 'yup'; import { useTranslation } from 'react-i18next'; -import { EditorState } from 'draft-js'; import { useLocation, useNavigate, useParams } from 'react-router-dom'; import { useLazyQuery, useQuery } from '@apollo/client'; import { setNotification } from 'common/notification'; diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index f117fd680..a7da957b1 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -1,5 +1,5 @@ import styles from './Editor.module.css'; -import { forwardRef, useCallback, useState } from 'react'; +import { forwardRef, useState } from 'react'; import { useEffect } from 'react'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; @@ -9,7 +9,7 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; import { useResizeDetector } from 'react-resize-detector'; import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; -import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW, createCommand } from 'lexical'; +import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW } from 'lexical'; import { ClickAwayListener, FormHelperText, IconButton, InputAdornment } from '@mui/material'; import { BeautifulMentionsPlugin, @@ -48,7 +48,7 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP const [showEmojiPicker, setShowEmojiPicker] = useState(false); const mentions = props.inputProp?.suggestions || []; const suggestions = { - '@': mentions?.map((el: any) => el?.split('@')[1]), + '@': mentions.map((el: any) => el?.split('@')[1]), }; const [editor] = useLexicalComposerContext(); diff --git a/src/containers/Template/Form/HSM/HSM.tsx b/src/containers/Template/Form/HSM/HSM.tsx index f56b7655c..b7c383aeb 100644 --- a/src/containers/Template/Form/HSM/HSM.tsx +++ b/src/containers/Template/Form/HSM/HSM.tsx @@ -1,6 +1,5 @@ import { useState } from 'react'; import { useQuery } from '@apollo/client'; -import { EditorState } from 'draft-js'; import { useTranslation } from 'react-i18next'; import { useParams, useLocation } from 'react-router-dom'; import Loading from 'components/UI/Layout/Loading/Loading'; diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index 8a059f272..dac882b62 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -1,7 +1,6 @@ import { useState, useEffect } from 'react'; import * as Yup from 'yup'; import { useLazyQuery, useMutation, useQuery } from '@apollo/client'; -import { EditorState } from 'draft-js'; import Typography from '@mui/material/Typography'; import { useNavigate, useLocation, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; @@ -301,7 +300,6 @@ const Template = ({ } else { exampleBody = exampleValue; } - const editorStateBody = getEditorFromContent(exampleValue); setExample(exampleValue); onExampleChange(exampleBody); From 336c4bb87401f1ad6795d65d8d570d21a17bb08a Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 09:33:47 +0530 Subject: [PATCH 06/36] draftjs wrapping up v1 --- .../UI/Form/EmojiInput/EmojiInput.tsx | 70 +++---------------- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 2 - src/containers/Template/Editor.tsx | 40 +---------- 3 files changed, 12 insertions(+), 100 deletions(-) diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index a095224dd..fd6683fc3 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -103,25 +103,7 @@ export const EmojiInput = ({ props.form.setFieldValue(name, updatedEditorState); }; - const handleKeyCommand = (command: any, editorState: any) => { - if (command === 'underline') { - return 'handled'; - } - if (command === 'bold') { - updateValue('**'); - } else if (command === 'italic') { - updateValue('__'); - } else { - const newState = RichUtils.handleKeyCommand(editorState, command); - if (newState) { - props.form.setFieldValue(name, newState); - return 'handled'; - } - } - return 'not-handled'; - }; - - const draftJsChange = (editorState: any) => { + const lexicalChange = (editorState: any) => { if (handleChange) { handleChange(editorState); } @@ -134,43 +116,6 @@ export const EmojiInput = ({ const mentions = props.inputProp?.suggestions || []; - const [open, setOpen] = useState(false); - const [suggestions, setSuggestions] = useState(mentions); - - const onOpenChange = (_open: boolean) => { - setOpen(_open); - }; - - const getSuggestions = useCallback(customSuggestionsFilter, []); - - const onSearchChange = ({ value: searchValue }: { value: string }) => { - setSuggestions(getSuggestions(searchValue, mentions)); - }; - - const inputProps = { - component: Editor, - editorState: value, - open, - readOnly: props.disabled, - suggestions, - onOpenChange, - onSearchChange, - handlePastedText: (text: string, html: string, editorState: EditorState) => { - const pastedBlocks = ContentState.createFromText(text).getBlockMap(); - const newState = Modifier.replaceWithFragment( - editorState.getCurrentContent(), - editorState.getSelection(), - pastedBlocks - ); - const newEditorState = EditorState.push(editorState, newState, 'insert-fragment'); - draftJsChange(newEditorState); - return 'handled'; - }, - handleKeyCommand, - onBlur: handleBlur, - onChange: draftJsChange, - }; - const emojiPicker = showEmojiPicker ? ( updateValue(emojiValue, true)} @@ -184,9 +129,16 @@ export const EmojiInput = ({ setShowEmojiPicker(false); }; + const emojiStyles = { + position: 'absolute', + bottom: '60px', + right: '-150px', + zIndex: 100, + }; + const picker = ( - + - {emojiPicker} + {showEmojiPicker && {}} displayStyle={emojiStyles} />} ); @@ -213,7 +165,7 @@ export const EmojiInput = ({ nodes: [BeautifulMentionNode], }} > - + ); diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 3f70a3313..a9d7fc532 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -96,8 +96,6 @@ export const WhatsAppEditor = ({ ) { sendMessage(editor?.getRootElement()?.textContent); } - // sendMessage() - // Prevent line break on enter } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { formatter = 'bold'; } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index a7da957b1..23593780b 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -38,14 +38,8 @@ export interface EditorProps { onChange?: any; } -type MentionsProps = { - mentions: any; -}; - export const Editor = ({ textArea = false, disabled = false, ...props }: EditorProps) => { const { field, form, picker, placeholder, onChange } = props; - - const [showEmojiPicker, setShowEmojiPicker] = useState(false); const mentions = props.inputProp?.suggestions || []; const suggestions = { '@': mentions.map((el: any) => el?.split('@')[1]), @@ -126,13 +120,6 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP }); }; - const emojiStyles = { - position: 'absolute', - bottom: '60px', - right: '-150px', - zIndex: 100, - }; - return (
    @@ -158,32 +145,7 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP /> {/* */} - {picker && ( - { - setShowEmojiPicker(false); - }} - > - - setShowEmojiPicker(!showEmojiPicker)} - > - - 😀 - - - - {showEmojiPicker && ( - {}} displayStyle={emojiStyles} /> - )} - - - )} + {picker && picker}
    {form && form.errors[field.name] && form.touched[field.name] ? ( {form.errors[field.name]} From f72f18c92a096160d41d0ea7e268bd675d80d3a8 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 09:39:56 +0530 Subject: [PATCH 07/36] draftjs wrapping up v2 --- .../UI/Form/EmojiInput/EmojiInput.tsx | 86 +------------------ src/containers/Template/Editor.tsx | 5 +- 2 files changed, 3 insertions(+), 88 deletions(-) diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index fd6683fc3..a2691f315 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -1,5 +1,4 @@ -import { useState, useMemo, useCallback, forwardRef } from 'react'; -import { RichUtils, Modifier, EditorState, ContentState } from 'draft-js'; +import { useState, useMemo, forwardRef } from 'react'; import createMentionPlugin from '@draft-js-plugins/mention'; import { InputAdornment, IconButton, ClickAwayListener } from '@mui/material'; @@ -22,58 +21,6 @@ export interface EmojiInputProps { inputProp?: any; } -const getMentionComponentAndPlugin = () => { - const mentionPlugin = createMentionPlugin({ - theme: Styles, - }); - const { MentionSuggestions } = mentionPlugin; - const plugins = [mentionPlugin]; - return { plugins, MentionSuggestions }; -}; - -const customSuggestionsFilter = (searchValue: string, suggestions: Array) => { - const size = (list: any) => (list.constructor.name === 'List' ? list.size : list.length); - - const get = (obj: any, attr: any) => (obj.get ? obj.get(attr) : obj[attr]); - - const value = searchValue.toLowerCase(); - const filteredSuggestions = suggestions.filter( - (suggestion) => !value || get(suggestion, 'name').toLowerCase().indexOf(value) > -1 - ); - - /** - * We can restrict no of values from dropdown using this - * Currently returning all values for give dropdown - */ - const length = size(filteredSuggestions); - return filteredSuggestions.slice(0, length); -}; - -const DraftField = forwardRef((inputProps: any, ref) => { - const { - component: Component, - open, - suggestions, - onOpenChange, - onSearchChange, - ...other - } = inputProps; - - const { MentionSuggestions, plugins } = useMemo(getMentionComponentAndPlugin, []); - - return ( - <> - - - - ); -}); - export const EmojiInput = ({ field: { value, name, onBlur }, handleChange, @@ -83,26 +30,6 @@ export const EmojiInput = ({ }: EmojiInputProps) => { const [showEmojiPicker, setShowEmojiPicker] = useState(false); - const updateValue = (input: any, isEmoji = false) => { - const editorContentState = value.getCurrentContent(); - const editorSelectionState: any = value.getSelection(); - const ModifiedContent = Modifier.replaceText( - editorContentState, - editorSelectionState, - isEmoji ? input.native : input - ); - let updatedEditorState = EditorState.push(value, ModifiedContent, 'insert-characters'); - if (!isEmoji) { - const editorSelectionStateMod = updatedEditorState.getSelection(); - const updatedSelection = editorSelectionStateMod.merge({ - anchorOffset: editorSelectionStateMod.getAnchorOffset() - 1, - focusOffset: editorSelectionStateMod.getFocusOffset() - 1, - }); - updatedEditorState = EditorState.forceSelection(updatedEditorState, updatedSelection); - } - props.form.setFieldValue(name, updatedEditorState); - }; - const lexicalChange = (editorState: any) => { if (handleChange) { handleChange(editorState); @@ -114,17 +41,6 @@ export const EmojiInput = ({ props.form.setFieldValue(name, editorState); }; - const mentions = props.inputProp?.suggestions || []; - - const emojiPicker = showEmojiPicker ? ( - updateValue(emojiValue, true)} - displayStyle={{ position: 'absolute', top: '10px', right: '0px', zIndex: 2 }} - /> - ) : ( - '' - ); - const handleClickAway = () => { setShowEmojiPicker(false); }; diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index 23593780b..ba1d75609 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -1,5 +1,5 @@ import styles from './Editor.module.css'; -import { forwardRef, useState } from 'react'; +import { forwardRef } from 'react'; import { useEffect } from 'react'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; @@ -10,13 +10,12 @@ import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; import { useResizeDetector } from 'react-resize-detector'; import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; import { KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW } from 'lexical'; -import { ClickAwayListener, FormHelperText, IconButton, InputAdornment } from '@mui/material'; +import { FormHelperText } from '@mui/material'; import { BeautifulMentionsPlugin, BeautifulMentionsMenuProps, BeautifulMentionsMenuItemProps, } from 'lexical-beautiful-mentions'; -import EmojiPicker from 'components/UI/EmojiPicker/EmojiPicker'; export interface EditorProps { type?: any; From 03d2948fa90230bac0ef2769c98effa71bbeacc6 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 09:41:33 +0530 Subject: [PATCH 08/36] draftjs wrapping up v2 --- src/components/UI/Form/EmojiInput/EmojiInput.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index a2691f315..154d07642 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -1,7 +1,5 @@ -import { useState, useMemo, forwardRef } from 'react'; -import createMentionPlugin from '@draft-js-plugins/mention'; +import { useState } from 'react'; import { InputAdornment, IconButton, ClickAwayListener } from '@mui/material'; - import { EmojiPicker } from 'components/UI/EmojiPicker/EmojiPicker'; import { Editor } from 'containers/Template/Editor'; import Styles from './EmojiInput.module.css'; From ab715fc1310154897e098de92826bfa1c7ec3d83 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 11:26:30 +0530 Subject: [PATCH 09/36] draftjs wrapping up v2 --- src/common/RichEditor.tsx | 8 --- src/components/UI/EmojiPicker/EmojiPicker.tsx | 17 +---- .../UI/Form/EmojiInput/EmojiInput.tsx | 66 ++++++++++++++----- .../WhatsAppEditor/WhatsAppEditor.module.css | 1 - .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 22 ------- .../Chat/ChatMessages/ChatInput/ChatInput.tsx | 23 +++++-- src/containers/Form/FormLayout.tsx | 3 +- .../InteractiveMessage.helper.ts | 15 ++--- .../InteractiveMessage/InteractiveMessage.tsx | 20 +++--- src/containers/Template/Editor.module.css | 3 + src/containers/Template/Editor.tsx | 35 ++++++---- src/containers/Template/Form/Template.tsx | 19 +++--- 12 files changed, 123 insertions(+), 109 deletions(-) diff --git a/src/common/RichEditor.tsx b/src/common/RichEditor.tsx index 4fe3b344f..62051c312 100644 --- a/src/common/RichEditor.tsx +++ b/src/common/RichEditor.tsx @@ -1,4 +1,3 @@ -import { EditorState, ContentState } from 'draft-js'; import CallIcon from '@mui/icons-material/Call'; import OpenInNewIcon from '@mui/icons-material/OpenInNew'; import { Interweave } from 'interweave'; @@ -8,13 +7,6 @@ import { UrlMatcher } from 'interweave-autolink'; const regexForLink = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi; -// Convert Draft.js to WhatsApp message format. -export const getPlainTextFromEditor = (editorState: any) => { - return editorState; -}; -export const getEditorFromContent = (text: string) => - EditorState.createWithContent(ContentState.createFromText(text)); - const isAlphanumeric = (c: any) => { const x = c.charCodeAt(); return (x >= 65 && x <= 90) || (x >= 97 && x <= 122) || (x >= 48 && x <= 57); diff --git a/src/components/UI/EmojiPicker/EmojiPicker.tsx b/src/components/UI/EmojiPicker/EmojiPicker.tsx index cf1cc42eb..2c8481300 100644 --- a/src/components/UI/EmojiPicker/EmojiPicker.tsx +++ b/src/components/UI/EmojiPicker/EmojiPicker.tsx @@ -1,28 +1,15 @@ import data from '@emoji-mart/data'; import Picker from '@emoji-mart/react'; -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; -import { $createTextNode, $getSelection, $isRangeSelection } from 'lexical'; + export interface EmojiPickerProps { displayStyle: object; onEmojiSelect: Function; } export const EmojiPicker = ({ displayStyle, onEmojiSelect }: EmojiPickerProps) => { - const [editor] = useLexicalComposerContext(); - return (
    - { - editor.update(() => { - const selection = $getSelection(); - if ($isRangeSelection(selection)) { - selection.insertNodes([$createTextNode(emoji.native)]); - } - }); - }} - /> +
    ); }; diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index 154d07642..fb7d5bb58 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -5,6 +5,8 @@ import { Editor } from 'containers/Template/Editor'; import Styles from './EmojiInput.module.css'; import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { BeautifulMentionNode } from 'lexical-beautiful-mentions'; +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; +import { $createTextNode, $getSelection, $isRangeSelection } from 'lexical'; export interface EmojiInputProps { field: any; @@ -43,6 +45,40 @@ export const EmojiInput = ({ setShowEmojiPicker(false); }; + const picker = ( + + ); + + const input = ( + console.log(error), + nodes: [BeautifulMentionNode], + }} + > + + + ); + + return input; +}; +interface EmojiPickerProps { + handleClickAway: any; + showEmojiPicker: any; + setShowEmojiPicker: any; +} +const EmojiPickerComponent = ({ + showEmojiPicker, + setShowEmojiPicker, + handleClickAway, +}: EmojiPickerProps) => { + const [editor] = useLexicalComposerContext(); + const emojiStyles = { position: 'absolute', bottom: '60px', @@ -50,7 +86,7 @@ export const EmojiInput = ({ zIndex: 100, }; - const picker = ( + return ( - {showEmojiPicker && {}} displayStyle={emojiStyles} />} + {showEmojiPicker && ( + { + editor.update(() => { + const selection = $getSelection(); + if ($isRangeSelection(selection)) { + selection.insertNodes([$createTextNode(emoji.native)]); + } + }); + }} + displayStyle={emojiStyles} + /> + )} ); - - const input = ( - console.log(error), - nodes: [BeautifulMentionNode], - }} - > - - - ); - - return input; }; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css index d33bb0247..3911a3262 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css @@ -39,7 +39,6 @@ span.emoji-mart-emoji { position: relative; tab-size: 1; outline: 0; - /* padding: 4px 10px; */ } .editorPlaceholder { diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index a9d7fc532..66f2d6e7f 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -1,7 +1,6 @@ import { useCallback } from 'react'; import { useEffect } from 'react'; -import { Modifier, EditorState } from 'draft-js'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; import { $getSelection, $createTextNode, $getRoot } from 'lexical'; @@ -21,27 +20,6 @@ interface WhatsAppEditorProps { readOnly?: boolean; } -export const updatedValue = (input: any, editorState: EditorState, isEmoji: boolean = false) => { - const editorContentState = editorState.getCurrentContent(); - const editorSelectionState: any = editorState.getSelection(); - const ModifiedContent = Modifier.replaceText( - editorContentState, - editorSelectionState, - isEmoji ? input.native : input - ); - let updatedEditorState = EditorState.push(editorState, ModifiedContent, 'insert-characters'); - if (!isEmoji) { - const editorSelectionStateMod = updatedEditorState.getSelection(); - const updatedSelection = editorSelectionStateMod.merge({ - anchorOffset: editorSelectionStateMod.getAnchorOffset() - 1, - focusOffset: editorSelectionStateMod.getFocusOffset() - 1, - }); - updatedEditorState = EditorState.forceSelection(updatedEditorState, updatedSelection); - } - - return updatedEditorState; -}; - export const WhatsAppEditor = ({ setEditorState, sendMessage, diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index 064bd659e..3478653e9 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -8,7 +8,6 @@ import AttachmentIconSelected from 'assets/images/icons/Attachment/Selected.svg? import VariableIcon from 'assets/images/icons/Template/Variable.svg?react'; import CrossIcon from 'assets/images/icons/Clear.svg?react'; import SendMessageIcon from 'assets/images/icons/SendMessage.svg?react'; -import { getEditorFromContent } from 'common/RichEditor'; import { is24HourWindowOver, pattern } from 'common/constants'; import SearchBar from 'components/UI/SearchBar/SearchBar'; import WhatsAppEditor from 'components/UI/Form/WhatsAppEditor/WhatsAppEditor'; @@ -24,7 +23,13 @@ import { VoiceRecorder } from '../VoiceRecorder/VoiceRecorder'; import ChatTemplates from '../ChatTemplates/ChatTemplates'; import styles from './ChatInput.module.css'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; -import { $createParagraphNode, $createTextNode, $getRoot } from 'lexical'; +import { + $createParagraphNode, + $createTextNode, + $getRoot, + $getSelection, + $isRangeSelection, +} from 'lexical'; export interface ChatInputProps { onSendMessage( @@ -244,7 +249,7 @@ export const ChatInput = ({ setSelectedTemplate(obj); // Conversion from HTML text to EditorState - setEditorState(getEditorFromContent(messageBody)); + setEditorState(messageBody); editor.update(() => { const root = $getRoot(); const paragraph = $createParagraphNode(); @@ -488,7 +493,17 @@ export const ChatInput = ({ {showEmojiPicker ? ( - {}} displayStyle={emojiStyles} /> + { + editor.update(() => { + const selection = $getSelection(); + if ($isRangeSelection(selection)) { + selection.insertNodes([$createTextNode(emoji.native)]); + } + }); + }} + displayStyle={emojiStyles} + /> ) : null}
    diff --git a/src/containers/Form/FormLayout.tsx b/src/containers/Form/FormLayout.tsx index 6d7723c08..af029f304 100644 --- a/src/containers/Form/FormLayout.tsx +++ b/src/containers/Form/FormLayout.tsx @@ -11,7 +11,6 @@ import { Dropdown } from 'components/UI/Form/Dropdown/Dropdown'; import { DialogBox } from 'components/UI/DialogBox/DialogBox'; import { Loading } from 'components/UI/Layout/Loading/Loading'; import { setNotification, setErrorMessage } from 'common/notification'; -import { getPlainTextFromEditor } from 'common/RichEditor'; import { SEARCH_QUERY_VARIABLES } from 'common/constants'; import { SEARCH_QUERY } from 'graphql/queries/Search'; import { USER_LANGUAGES } from 'graphql/queries/Organization'; @@ -397,7 +396,7 @@ export const FormLayout = ({ additionalState(payload[field.additionalState]); } if (field.convertToWhatsApp && payload[field.name]) { - payload[field.name] = getPlainTextFromEditor(payload[field.name]); + payload[field.name] = payload[field.name]; } if (field.skipPayload) { delete payload[field.name]; diff --git a/src/containers/InteractiveMessage/InteractiveMessage.helper.ts b/src/containers/InteractiveMessage/InteractiveMessage.helper.ts index 3e3219a8f..a0bb19aab 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.helper.ts +++ b/src/containers/InteractiveMessage/InteractiveMessage.helper.ts @@ -1,6 +1,5 @@ import axios from 'axios'; import { LIST, LOCATION_REQUEST, QUICK_REPLY } from 'common/constants'; -import { getPlainTextFromEditor } from 'common/RichEditor'; import { FLOW_EDITOR_API } from 'config'; import { getAuthSession } from 'services/AuthService'; import * as Yup from 'yup'; @@ -38,13 +37,11 @@ export const validator = (templateType: any, t: any) => { title: Yup.string() .required(t('Title is required')) .max(60, t('Title can be at most 60 characters')), - body: Yup.string() - // .transform((_current, original) => original.getCurrentContent().getPlainText()) - .when('type', { - is: (val: any) => val && val.id && val.id === 'DOCUMENT', - then: (schema) => schema.nullable(), - otherwise: (schema) => schema.required(t('Message content is required.')), - }), + body: Yup.string().when('type', { + is: (val: any) => val && val.id && val.id === 'DOCUMENT', + then: (schema) => schema.nullable(), + otherwise: (schema) => schema.required(t('Message content is required.')), + }), }; if (templateType === LIST) { @@ -267,7 +264,7 @@ export const getPayloadByMediaType = (mediaType: string, payload: any) => { break; } - result.text = getPlainTextFromEditor(payload.body); + result.text = payload.body; result.caption = payload.footer; return result; diff --git a/src/containers/InteractiveMessage/InteractiveMessage.tsx b/src/containers/InteractiveMessage/InteractiveMessage.tsx index b2044fc78..52d57c28a 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.tsx @@ -23,7 +23,6 @@ import { LanguageBar } from 'components/UI/LanguageBar/LanguageBar'; import { LIST, LOCATION_REQUEST, MEDIA_MESSAGE_TYPES, QUICK_REPLY } from 'common/constants'; import { validateMedia } from 'common/utils'; import Loading from 'components/UI/Layout/Loading/Loading'; -import { getPlainTextFromEditor, getEditorFromContent } from 'common/RichEditor'; import { InteractiveOptions } from './InteractiveOptions/InteractiveOptions'; import styles from './InteractiveMessage.module.css'; import { @@ -89,6 +88,11 @@ export const InteractiveMessage = () => { fetchPolicy: 'network-only', }); + let isEditing = false; + if (params.id) { + isEditing = true; + } + // alter header & update/copy queries let header; @@ -160,7 +164,7 @@ export const InteractiveMessage = () => { setTitle(data.title); setFooter(data.footer); - setBody(getEditorFromContent(data.body)); + setBody(data.body); setTemplateType(typeValue); setTemplateTypeField(templateTypeOptions.find((option) => option.id === typeValue)); setTimeout(() => setTemplateButtons(data.templateButtons), 100); @@ -229,7 +233,7 @@ export const InteractiveMessage = () => { setTitle(titleText); setFooter(data.footer); - setBody(getEditorFromContent(data.body)); + setBody(data.body); setTemplateType(typeValue); setTemplateTypeField(templateTypeOptions.find((option) => option.id === typeValue)); setTimeout(() => setTemplateButtons(data.templateButtons), 100); @@ -448,7 +452,7 @@ export const InteractiveMessage = () => { setNextLanguage(option); const { values, errors } = form; if (values.type?.label === 'TEXT') { - if (values.title || values.body.getCurrentContent().getPlainText()) { + if (values.title || values.body) { if (errors) { setNotification(t('Please check the errors'), 'warning'); } @@ -456,7 +460,7 @@ export const InteractiveMessage = () => { handleLanguageChange(option); } } - if (values.body.getCurrentContent().getPlainText()) { + if (values.body) { if (Object.keys(errors).length !== 0) { setNotification(t('Please check the errors'), 'warning'); } @@ -614,7 +618,7 @@ export const InteractiveMessage = () => { } if (templateTypeVal === LIST) { - const bodyText = getPlainTextFromEditor(payload.body); + const bodyText = payload.body; const items = getTemplateButtonPayload(templateTypeVal, templateButtonVal); const globalButtons = [{ type: 'text', title: globalButtonVal }]; @@ -626,7 +630,7 @@ export const InteractiveMessage = () => { } if (templateType === LOCATION_REQUEST) { - const bodyText = getPlainTextFromEditor(payload.body); + const bodyText = payload.body; const locationJson = { type: 'location_request_message', body: { @@ -770,7 +774,7 @@ export const InteractiveMessage = () => { const validationScheme = Yup.object().shape(validation, [['type', 'attachmentURL']]); const getPreviewData = () => { - const bodyText = getPlainTextFromEditor(body); + const bodyText = body; if (!title && !bodyText && !footer) return null; const payload = { diff --git a/src/containers/Template/Editor.module.css b/src/containers/Template/Editor.module.css index 9b0644d56..35831b96c 100644 --- a/src/containers/Template/Editor.module.css +++ b/src/containers/Template/Editor.module.css @@ -45,6 +45,9 @@ tab-size: 1; outline: 0; } +.EditorInput p { + overflow: scroll !important; +} .boxii { background-color: red !important; diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index ba1d75609..dc3662a9a 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -16,6 +16,7 @@ import { BeautifulMentionsMenuProps, BeautifulMentionsMenuItemProps, } from 'lexical-beautiful-mentions'; +import { useParams } from 'react-router'; export interface EditorProps { type?: any; @@ -43,9 +44,27 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP const suggestions = { '@': mentions.map((el: any) => el?.split('@')[1]), }; + const params = useParams(); + + let isEditing = false; + if (params.id) { + isEditing = true; + } const [editor] = useLexicalComposerContext(); + useEffect(() => { + if (field.value && isEditing) { + editor.update(() => { + const root = $getRoot(); + root.clear(); + const paragraph = $createParagraphNode(); + paragraph.append($createTextNode(field.value || '')); + root.append(paragraph); + }); + } + }, [field]); + const { ref } = useResizeDetector({ refreshMode: 'debounce', refreshRate: 1000, @@ -55,16 +74,6 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP return

    {placeholder}

    ; }; - useEffect(() => { - editor.update(() => { - const root = $getRoot(); - root.clear(); - const paragraph = $createParagraphNode(); - paragraph.append($createTextNode(field.value || '')); - root.append(paragraph); - }); - }, []); - const handleFormatting = (text: string, formatter: string) => { switch (formatter) { case 'bold': @@ -85,7 +94,6 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP return editor.registerCommand( KEY_DOWN_COMMAND, (event: KeyboardEvent) => { - // Handle event here let formatter = ''; if (event.code === 'Enter') { event.preventDefault(); // Prevent line break on enter @@ -115,7 +123,9 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP const handleChange = (editorState: any) => { editorState.read(() => { const root = $getRoot(); - onChange(root.getTextContent()); + if (!isEditing) { + onChange(root.getTextContent()); + } }); }; @@ -142,7 +152,6 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP triggers={['@']} items={suggestions} /> - {/* */} {picker && picker}
diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index dac882b62..ee97d8583 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -23,7 +23,6 @@ import { QUICK_REPLY, VALID_URL_REGEX, } from 'common/constants'; -import { getPlainTextFromEditor, getEditorFromContent } from 'common/RichEditor'; import Loading from 'components/UI/Layout/Loading/Loading'; import { CreateAutoComplete } from 'components/UI/Form/CreateAutoComplete/CreateAutoComplete'; import { validateMedia } from 'common/utils'; @@ -33,7 +32,6 @@ const regexForShortcode = /^[a-z0-9_]+$/g; const HSMValidation = { example: Yup.string() - // .transform((_current, original) => original.getCurrentContent().getPlainText()) .max(1024, 'Maximum 1024 characters are allowed') .when('body', ([body], schema: any) => schema.test({ @@ -495,7 +493,7 @@ const Template = ({ // Removing buttons when checkbox is checked or unchecked useEffect(() => { if (getExample) { - const { message }: any = getTemplateAndButton(getPlainTextFromEditor(getExample)); + const { message }: any = getTemplateAndButton(getExample); onExampleChange(message || ''); } }, [isAddButtonChecked]); @@ -507,7 +505,7 @@ const Template = ({ const parsedText = parse.length ? `| ${parse.join(' | ')}` : null; - const { message }: any = getTemplateAndButton(getPlainTextFromEditor(example)); + const { message }: any = getTemplateAndButton(example); const sampleText: any = parsedText && message + parsedText; @@ -631,7 +629,7 @@ const Template = ({ const onLanguageChange = (option: string, form: any) => { setNextLanguage(option); const { values } = form; - if (values.label || values.body.getCurrentContent().getPlainText()) { + if (values.label || values.body) { return; } handleLanguageChange(option); @@ -773,15 +771,15 @@ const Template = ({ }, []); // get template body - const templateBody = getTemplateAndButton(getPlainTextFromEditor(body)); - const templateExample = getTemplateAndButton(getPlainTextFromEditor(example)); + const templateBody = getTemplateAndButton(body); + const templateExample = getTemplateAndButton(example); return { hasButtons: true, buttons: JSON.stringify(buttons), buttonType: templateType, - body: getEditorFromContent(templateBody.message), - example: getEditorFromContent(templateExample.message), + body: templateBody.message, + example: templateExample.message, }; }; @@ -837,7 +835,7 @@ const Template = ({ status: 'approved', languageId: language, label: payloadCopy.label, - body: getPlainTextFromEditor(payloadCopy.body), + body: payloadCopy.body, MessageMedia: messageMedia, ...defaultAttribute, }; @@ -907,7 +905,6 @@ const Template = ({ language: Yup.object().nullable().required('Language is required.'), label: Yup.string().required(t('Title is required.')).max(50, t('Title length is too long.')), body: Yup.string() - // .transform((current, original) => original.getCurrentContent().getPlainText()) .required(t('Message is required.')) .max(1024, 'Maximum 1024 characters are allowed'), type: Yup.object() From fc5ca0391a54ce2be03f7c63d7b3deb8f0dda7f9 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 11:30:58 +0530 Subject: [PATCH 10/36] draftjs wrapping up v2 --- src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx | 2 +- src/containers/InteractiveMessage/InteractiveMessage.tsx | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index 3478653e9..c95215e3a 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -517,7 +517,7 @@ export const ChatInput = ({ onClick={() => { submitMessage(editorState); }} - // disabled={(!attachmentAdded && !recordedAudio) || uploading} + disabled={(!editorState && !attachmentAdded && !recordedAudio) || uploading} > diff --git a/src/containers/InteractiveMessage/InteractiveMessage.tsx b/src/containers/InteractiveMessage/InteractiveMessage.tsx index 52d57c28a..312925280 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.tsx @@ -88,11 +88,6 @@ export const InteractiveMessage = () => { fetchPolicy: 'network-only', }); - let isEditing = false; - if (params.id) { - isEditing = true; - } - // alter header & update/copy queries let header; From d8c6aa446a3e199f7299e42c3cc83746ac25043b Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 23:36:06 +0530 Subject: [PATCH 11/36] updated test cases --- .../UI/Form/EmojiInput/EmojiInput.tsx | 12 +-- .../WhatsAppEditor/WhatsAppEditor.test.tsx | 59 +++++++++++---- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 2 +- .../UI/MessageDialog/MessageDialog.test.tsx | 10 ++- .../UI/MessageDialog/MessageDialog.tsx | 22 ++++-- .../ChatMessages/ChatInput/ChatInput.test.tsx | 55 ++++++++++++-- .../InteractiveMessage/InteractiveMessage.tsx | 44 +++++------ src/containers/Template/Editor.tsx | 75 ++++++++++--------- .../Form/SpeedSend/SpeedSend.test.tsx | 2 +- src/jestconfig.mock.ts | 14 ++++ src/setupTests.ts | 14 ++++ 11 files changed, 216 insertions(+), 93 deletions(-) create mode 100644 src/jestconfig.mock.ts diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index fb7d5bb58..0c9616ed3 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -21,6 +21,12 @@ export interface EmojiInputProps { inputProp?: any; } +interface EmojiPickerProps { + handleClickAway: any; + showEmojiPicker: any; + setShowEmojiPicker: any; +} + export const EmojiInput = ({ field: { value, name, onBlur }, handleChange, @@ -67,11 +73,7 @@ export const EmojiInput = ({ return input; }; -interface EmojiPickerProps { - handleClickAway: any; - showEmojiPicker: any; - setShowEmojiPicker: any; -} + const EmojiPickerComponent = ({ showEmojiPicker, setShowEmojiPicker, diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx index 806783fc3..de410184f 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx @@ -3,8 +3,10 @@ import draftJs, { EditorState, ContentState } from 'draft-js'; import { vi } from 'vitest'; import WhatsAppEditor from './WhatsAppEditor'; +import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { userEvent } from '@testing-library/user-event'; -const mockHandleKeyCommand = vi.fn(); +const mockHandleFormatting = vi.fn(); const mockObserve = vi.fn(); global.ResizeObserver = vi.fn().mockImplementation(() => ({ @@ -19,7 +21,7 @@ vi.spyOn(draftJs, 'Editor').mockImplementation((props: any, _context: any) => { data-testid="editor" onClick={() => { props.handleKeyCommand('underline'); - mockHandleKeyCommand(); + mockHandleFormatting(); }} onChange={(event) => props.onChange(event)} > @@ -32,34 +34,63 @@ describe('', () => { const sendMessage = vi.fn(); const setEditorState = vi.fn(); - const defaultProps = (editorState: any) => { + const defaultProps = () => { return { handleHeightChange: handleHeightChange, sendMessage: sendMessage, - editorState: editorState, setEditorState: setEditorState, }; }; const editorContent = EditorState.createWithContent(ContentState.createFromText('Hello')); - test('input change should trigger callBacks', () => { - const { getByTestId } = render(); - fireEvent.change(getByTestId('editor'), { - target: { value: 10 }, - }); + test('input change should trigger callBacks', async () => { + const { getByTestId } = render( + console.log(error), + }} + > + + + ); + + await userEvent.click(getByTestId('editor')); + await userEvent.keyboard('10'); + + console.log(getByTestId('editor').innerText); + expect(setEditorState).toHaveBeenCalled(); }); - test('handleKeyCommand should work with new commands', () => { - const { getByTestId } = render(); - fireEvent.click(getByTestId('editor')); + test('handleKeyCommand should work with new commands', async () => { + const { getByTestId } = render( + console.log(error), + }} + > + + + ); + await userEvent.click(getByTestId('editor')); - expect(mockHandleKeyCommand).toHaveBeenCalled(); + expect(mockHandleFormatting).toHaveBeenCalled(); }); test('resize observer event is called', async () => { - render(); + render( + console.log(error), + }} + > + + + ); await waitFor(() => { expect(mockObserve).toHaveBeenCalled(); }); diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 66f2d6e7f..70894125a 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -106,7 +106,7 @@ export const WhatsAppEditor = ({ } - contentEditable={} + contentEditable={} ErrorBoundary={LexicalErrorBoundary} /> diff --git a/src/components/UI/MessageDialog/MessageDialog.test.tsx b/src/components/UI/MessageDialog/MessageDialog.test.tsx index d127b0e75..4c0e03f02 100644 --- a/src/components/UI/MessageDialog/MessageDialog.test.tsx +++ b/src/components/UI/MessageDialog/MessageDialog.test.tsx @@ -3,6 +3,7 @@ import { MockedProvider } from '@apollo/client/testing'; import { MessageDialog } from './MessageDialog'; import { getAttachmentPermissionMock } from 'mocks/Attachment'; +import { LexicalComposer } from '@lexical/react/LexicalComposer'; const handleClose = vi.fn(); @@ -13,7 +14,14 @@ const defaultProps = { }; const wrapper = ( - + console.log(error), + }} + > + + ); diff --git a/src/components/UI/MessageDialog/MessageDialog.tsx b/src/components/UI/MessageDialog/MessageDialog.tsx index fbcd0c2bc..32330962e 100644 --- a/src/components/UI/MessageDialog/MessageDialog.tsx +++ b/src/components/UI/MessageDialog/MessageDialog.tsx @@ -3,6 +3,7 @@ import { Dialog, DialogContent } from '@mui/material'; import CrossDarkIcon from 'assets/images/icons/CrossDark.svg?react'; import ChatInput from 'containers/Chat/ChatMessages/ChatInput/ChatInput'; import styles from './MessageDialog.module.css'; +import { LexicalComposer } from '@lexical/react/LexicalComposer'; export interface MessageDialogProps { title: string; @@ -21,13 +22,20 @@ export const MessageDialog = ({ title, onSendMessage, handleClose }: MessageDial
{title}
- {}} - contactStatus="" - contactBspStatus="SESSION_AND_HSM" - additionalStyle={styles.ChatInput} - /> + console.log(error), + }} + > + {}} + contactStatus="" + contactBspStatus="SESSION_AND_HSM" + additionalStyle={styles.ChatInput} + /> + diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx index bc9f88ced..88a58de1c 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx @@ -11,6 +11,7 @@ import { } from 'mocks/Attachment'; import { searchInteractive } from 'mocks/InteractiveMessage'; import '../VoiceRecorder/VoiceRecorder'; +import { LexicalComposer } from '@lexical/react/LexicalComposer'; const mocks = [ searchInteractive, @@ -68,7 +69,14 @@ describe('', () => { const chatInput = ( - + console.log(error), + }} + > + + ); @@ -170,7 +178,14 @@ describe('', () => { propsWithBspStatusNone.contactBspStatus = 'NONE'; const { getByText } = render( - + console.log(error), + }} + > + + ); @@ -186,7 +201,14 @@ describe('', () => { propsWithBspStatusHSM.contactBspStatus = 'HSM'; const { getByText } = render( - + console.log(error), + }} + > + + ); expect(getByText('Templates')).toBeInTheDocument(); @@ -197,7 +219,14 @@ describe('', () => { propsWithBspStatusSession.contactBspStatus = 'SESSION'; const { getByText } = render( - + console.log(error), + }} + > + + ); expect(getByText('Speed sends')).toBeInTheDocument(); @@ -211,7 +240,14 @@ describe('', () => { const { getByText } = render( - + console.log(error), + }} + > + + ); expect(getByText('Templates')).toBeInTheDocument(); @@ -223,7 +259,14 @@ describe('', () => { propsWithMockSend.onSendMessage = sendMessageMock; const { getByText, getByTestId } = render( - + console.log(error), + }} + > + + ); diff --git a/src/containers/InteractiveMessage/InteractiveMessage.tsx b/src/containers/InteractiveMessage/InteractiveMessage.tsx index 312925280..4f628267f 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.tsx @@ -810,27 +810,29 @@ export const InteractiveMessage = () => { return ( <> - + {!loadingTemplate && ( + + )}
{ + const [editorState, setEditorState] = useState(''); const { field, form, picker, placeholder, onChange } = props; const mentions = props.inputProp?.suggestions || []; const suggestions = { @@ -54,7 +55,7 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP const [editor] = useLexicalComposerContext(); useEffect(() => { - if (field.value && isEditing) { + if (field.value && isEditing && !editorState) { editor.update(() => { const root = $getRoot(); root.clear(); @@ -63,7 +64,7 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP root.append(paragraph); }); } - }, [field]); + }, [field.value]); const { ref } = useResizeDetector({ refreshMode: 'debounce', @@ -87,44 +88,41 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP } }; - const MyCustomAutoFocusPlugin = () => { - const [editor] = useLexicalComposerContext(); - - useEffect(() => { - return editor.registerCommand( - KEY_DOWN_COMMAND, - (event: KeyboardEvent) => { - let formatter = ''; - if (event.code === 'Enter') { - event.preventDefault(); // Prevent line break on enter - } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { - formatter = 'bold'; - } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { - formatter = 'italic'; + useEffect(() => { + return editor.registerCommand( + KEY_DOWN_COMMAND, + (event: KeyboardEvent) => { + let formatter = ''; + if (event.code === 'Enter') { + event.preventDefault(); // Prevent line break on enter + } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { + formatter = 'bold'; + } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { + formatter = 'italic'; + } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyS') { + formatter = 'strikethrough'; + } + + editor.update(() => { + const selection = $getSelection(); + if (selection?.getTextContent() && formatter) { + const text = handleFormatting(selection?.getTextContent(), formatter); + const newNode = $createTextNode(text); + selection?.insertNodes([newNode]); } - - editor.update(() => { - const selection = $getSelection(); - if (selection?.getTextContent() && formatter) { - const text = handleFormatting(selection?.getTextContent(), formatter); - const newNode = $createTextNode(text); - selection?.insertNodes([newNode]); - } - }); - return false; - }, - COMMAND_PRIORITY_LOW - ); - }, [editor]); - - return null; - }; + }); + return false; + }, + COMMAND_PRIORITY_LOW + ); + }, [editor]); const handleChange = (editorState: any) => { editorState.read(() => { const root = $getRoot(); - if (!isEditing) { + if (!disabled) { onChange(root.getTextContent()); + setEditorState(root.getTextContent()); } }); }; @@ -138,14 +136,17 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP contentEditable={
- +
} ErrorBoundary={LexicalErrorBoundary} /> - { cleanup(); }); diff --git a/src/jestconfig.mock.ts b/src/jestconfig.mock.ts new file mode 100644 index 000000000..6bee50ba9 --- /dev/null +++ b/src/jestconfig.mock.ts @@ -0,0 +1,14 @@ +import jest +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: jest.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: jest.fn(), // deprecated + removeListener: jest.fn(), // deprecated + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), + })), +}); diff --git a/src/setupTests.ts b/src/setupTests.ts index 907df043e..b0a3ff995 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -11,6 +11,20 @@ afterEach(() => { import.meta.env.VITE_WEB_SOCKET = 'ws://localhost/socket'; +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}); + vi.mock('react-media-recorder', () => { return { useReactMediaRecorder: () => { From d870c36b384c4d5f4832683830163e50c1d39e68 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 23:43:52 +0530 Subject: [PATCH 12/36] updated test cases --- .../InteractiveMessage/InteractiveMessage.tsx | 44 +++++++++---------- src/jestconfig.mock.ts | 14 ------ 2 files changed, 21 insertions(+), 37 deletions(-) delete mode 100644 src/jestconfig.mock.ts diff --git a/src/containers/InteractiveMessage/InteractiveMessage.tsx b/src/containers/InteractiveMessage/InteractiveMessage.tsx index 4f628267f..312925280 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.tsx @@ -810,29 +810,27 @@ export const InteractiveMessage = () => { return ( <> - {!loadingTemplate && ( - - )} +
({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // deprecated - removeListener: jest.fn(), // deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - })), -}); From 156c419a9db31a2172315143097cb30f3a83d7c7 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 9 Feb 2024 23:44:35 +0530 Subject: [PATCH 13/36] updated test cases --- src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx index de410184f..63baf0a9e 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx @@ -1,4 +1,4 @@ -import { render, fireEvent, waitFor } from '@testing-library/react'; +import { render, waitFor } from '@testing-library/react'; import draftJs, { EditorState, ContentState } from 'draft-js'; import { vi } from 'vitest'; From bdbb22827c40b831d44e78118074398085464981 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Mon, 12 Feb 2024 00:42:59 +0530 Subject: [PATCH 14/36] updated test cases --- .../UI/Form/EmojiInput/EmojiInput.test.tsx | 21 ++-------- .../UI/Form/EmojiInput/EmojiInput.tsx | 6 ++- .../WhatsAppEditor/WhatsAppEditor.test.tsx | 38 ++++++------------- .../InteractiveMessage.test.tsx | 23 +++++++++-- src/containers/Template/Editor.tsx | 3 +- src/containers/Template/Form/HSM/HSM.test.tsx | 1 + .../Form/SpeedSend/SpeedSend.test.tsx | 24 +++++++++++- .../Template/Form/Template.test.tsx | 1 + src/matchMediMock.ts | 13 +++++++ src/setupTests.ts | 14 ------- 10 files changed, 80 insertions(+), 64 deletions(-) create mode 100644 src/matchMediMock.ts diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx index c69ad9217..d1dc2b8f3 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx @@ -1,23 +1,10 @@ +import '../../../../matchMediMock'; import { render } from '@testing-library/react'; import { EmojiInput } from './EmojiInput'; -import { EditorState } from 'draft-js'; import userEvent from '@testing-library/user-event'; const setFieldValueMock = vi.fn(); -Object.defineProperty(window, 'matchMedia', { - writable: true, - value: (query: any) => { - return { - matches: false, - media: query, - onchange: null, - addListener: vi.fn(), - removeListener: vi.fn(), - }; - }, -}); - const mockIntersectionObserver = class { constructor() {} observe() {} @@ -32,10 +19,10 @@ const wrapper = ( form={{ touched: false, errors: {}, - values: { input: EditorState.createEmpty() }, + values: { input: '' }, setFieldValue: setFieldValueMock, }} - field={{ name: 'input', value: EditorState.createEmpty(), onChange: vi.fn() }} + field={{ name: 'input', value: '', onChange: vi.fn() }} label="Title" placeholder="Title" rows={10} @@ -43,7 +30,7 @@ const wrapper = ( ); it('renders component', () => { const { getByTestId } = render(wrapper); - expect(getByTestId('input')).toBeInTheDocument(); + expect(getByTestId('editor')).toBeInTheDocument(); }); it('should have a emoji picker', () => { diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index 0c9616ed3..661ad196c 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -6,7 +6,11 @@ import Styles from './EmojiInput.module.css'; import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { BeautifulMentionNode } from 'lexical-beautiful-mentions'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; -import { $createTextNode, $getSelection, $isRangeSelection } from 'lexical'; +import { + $createTextNode, + $getSelection, + $isRangeSelection, +} from 'lexical'; export interface EmojiInputProps { field: any; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx index 63baf0a9e..467754328 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx @@ -1,13 +1,10 @@ -import { render, waitFor } from '@testing-library/react'; -import draftJs, { EditorState, ContentState } from 'draft-js'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { vi } from 'vitest'; import WhatsAppEditor from './WhatsAppEditor'; import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { userEvent } from '@testing-library/user-event'; -const mockHandleFormatting = vi.fn(); - const mockObserve = vi.fn(); global.ResizeObserver = vi.fn().mockImplementation(() => ({ observe: mockObserve, @@ -15,20 +12,6 @@ global.ResizeObserver = vi.fn().mockImplementation(() => ({ disconnect: vi.fn(), })); -vi.spyOn(draftJs, 'Editor').mockImplementation((props: any, _context: any) => { - const input: any = ( - { - props.handleKeyCommand('underline'); - mockHandleFormatting(); - }} - onChange={(event) => props.onChange(event)} - > - ); - return input; -}); - describe('', () => { const handleHeightChange = vi.fn(); const sendMessage = vi.fn(); @@ -42,8 +25,6 @@ describe('', () => { }; }; - const editorContent = EditorState.createWithContent(ContentState.createFromText('Hello')); - test('input change should trigger callBacks', async () => { const { getByTestId } = render( ', () => { await userEvent.click(getByTestId('editor')); await userEvent.keyboard('10'); - - console.log(getByTestId('editor').innerText); - expect(setEditorState).toHaveBeenCalled(); }); - test('handleKeyCommand should work with new commands', async () => { + test('text is changed in lexical editor', async () => { const { getByTestId } = render( ', () => { ); - await userEvent.click(getByTestId('editor')); - expect(mockHandleFormatting).toHaveBeenCalled(); + const editor = screen.getByTestId('editor'); + console.log(editor); + + await userEvent.click(editor); + await userEvent.tab(); + fireEvent.input(editor, { data: 'test' }); + + await waitFor(() => { + expect(editor).toHaveTextContent('test'); + }); }); test('resize observer event is called', async () => { diff --git a/src/containers/InteractiveMessage/InteractiveMessage.test.tsx b/src/containers/InteractiveMessage/InteractiveMessage.test.tsx index 0d44d2d14..4c8034d8e 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.test.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.test.tsx @@ -1,3 +1,4 @@ +import '../../matchMediMock'; import { render, screen, waitFor, fireEvent } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import axios from 'axios'; @@ -8,6 +9,16 @@ import { setUserSession } from 'services/AuthService'; import { mocks } from 'mocks/InteractiveMessage'; import { InteractiveMessage } from './InteractiveMessage'; import { FLOW_EDITOR_API } from 'config'; +import { userEvent } from '@testing-library/user-event'; + +const mockIntersectionObserver = class { + constructor() {} + observe() {} + unobserve() {} + disconnect() {} +}; + +(window as any).IntersectionObserver = mockIntersectionObserver; const mockUseLocationValue: any = { pathname: '/', @@ -99,21 +110,23 @@ test('it renders empty interactive form', async () => { await waitFor(() => { // Get all input elements - const [title, quickReply1, quickReply2, , attachmentUrl] = screen.getAllByRole('textbox'); + const [title, lexicalEditor, quickReply1, quickReply2, , attachmentUrl] = + screen.getAllByRole('textbox'); expect(title).toBeInTheDocument(); expect(quickReply1).toBeInTheDocument(); expect(quickReply2).toBeInTheDocument(); expect(attachmentUrl).toBeInTheDocument(); fireEvent.change(title, { target: { value: 'new title' } }); - fireEvent.blur(title); + userEvent.click(lexicalEditor); + userEvent.keyboard('Yes'); fireEvent.change(quickReply1, { target: { value: 'Yes' } }); fireEvent.change(quickReply2, { target: { value: 'No' } }); fireEvent.change(attachmentUrl, { target: { value: 'https://picsum.photos/200/300' } }); fireEvent.blur(attachmentUrl); }); - // Changing language to marathi + // // Changing language to marathi await waitFor(() => { const language = screen.getByText('Marathi'); expect(language).toBeInTheDocument(); @@ -135,7 +148,9 @@ test('it renders empty interactive form', async () => { await waitFor(() => { // Adding list data - const [, header, listTitle, listItemTitle, listItemDesc] = screen.getAllByRole('textbox'); + // [title, lexicalEditor, quickReply1, quickReply2, , attachmentUrl] + const [, , header, listTitle, listItemTitle, listItemDesc] = screen.getAllByRole('textbox'); + expect(header).toBeInTheDocument(); expect(listTitle).toBeInTheDocument(); expect(listItemTitle).toBeInTheDocument(); diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index a21636d01..584d101b6 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -43,7 +43,7 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP const { field, form, picker, placeholder, onChange } = props; const mentions = props.inputProp?.suggestions || []; const suggestions = { - '@': mentions.map((el: any) => el?.split('@')[1]), + '@': mentions, }; const params = useParams(); @@ -147,6 +147,7 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP ErrorBoundary={LexicalErrorBoundary} /> + {/* {' '} */} { cleanup(); }); const mocks = TEMPLATE_MOCKS; setUserSession(JSON.stringify({ roles: ['Admin'] })); +const mockIntersectionObserver = class { + constructor() {} + observe() {} + unobserve() {} + disconnect() {} +}; + +(window as any).IntersectionObserver = mockIntersectionObserver; + +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: (query: any) => { + return { + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), + removeListener: vi.fn(), + }; + }, +}); + describe('SpeedSend', () => { test('cancel button should redirect to SpeedSendlist page', async () => { const { container, getByText } = render( diff --git a/src/containers/Template/Form/Template.test.tsx b/src/containers/Template/Form/Template.test.tsx index 40b95b5ac..8c4071f9c 100644 --- a/src/containers/Template/Form/Template.test.tsx +++ b/src/containers/Template/Form/Template.test.tsx @@ -1,3 +1,4 @@ +import '../../../matchMediMock' import { render, waitFor, cleanup, fireEvent } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import { BrowserRouter } from 'react-router-dom'; diff --git a/src/matchMediMock.ts b/src/matchMediMock.ts new file mode 100644 index 000000000..a58eb6f09 --- /dev/null +++ b/src/matchMediMock.ts @@ -0,0 +1,13 @@ +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}); diff --git a/src/setupTests.ts b/src/setupTests.ts index b0a3ff995..907df043e 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -11,20 +11,6 @@ afterEach(() => { import.meta.env.VITE_WEB_SOCKET = 'ws://localhost/socket'; -Object.defineProperty(window, 'matchMedia', { - writable: true, - value: vi.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: vi.fn(), // deprecated - removeListener: vi.fn(), // deprecated - addEventListener: vi.fn(), - removeEventListener: vi.fn(), - dispatchEvent: vi.fn(), - })), -}); - vi.mock('react-media-recorder', () => { return { useReactMediaRecorder: () => { From 1e582496413bcdddc21a28e927f9d12a69879e99 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Mon, 12 Feb 2024 00:56:33 +0530 Subject: [PATCH 15/36] updated test cases --- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 4 + src/containers/Form/FormLayout.tsx | 1 - src/containers/Template/Editor.module.css | 101 +----------------- src/containers/Template/Editor.tsx | 3 +- 4 files changed, 10 insertions(+), 99 deletions(-) diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 70894125a..fa90f55e1 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -69,9 +69,13 @@ export const WhatsAppEditor = ({ event.preventDefault(); if ( + editor && editor.getRootElement()?.textContent && typeof editor.getRootElement()?.textContent === 'string' ) { + sendMessage(editor.getRootElement()?.textContent); + } + { sendMessage(editor?.getRootElement()?.textContent); } } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { diff --git a/src/containers/Form/FormLayout.tsx b/src/containers/Form/FormLayout.tsx index af029f304..e8cfd94b9 100644 --- a/src/containers/Form/FormLayout.tsx +++ b/src/containers/Form/FormLayout.tsx @@ -527,7 +527,6 @@ export const FormLayout = ({ validationSchema={validationSchema} onSubmit={(itemData, { setErrors }) => { // when you want to show custom error on form field and error message is not coming from api - setCustomError({ setErrors }); saveHandler(itemData); }} diff --git a/src/containers/Template/Editor.module.css b/src/containers/Template/Editor.module.css index 35831b96c..d4b19eb00 100644 --- a/src/containers/Template/Editor.module.css +++ b/src/containers/Template/Editor.module.css @@ -45,36 +45,15 @@ tab-size: 1; outline: 0; } + .EditorInput p { overflow: scroll !important; } -.boxii { - background-color: red !important; -} - .EditorWrapper { margin: 1rem 0; } -.Multiline { - padding-bottom: 35px !important; -} - -.OutlineInput > div:first-child { - width: inherit !important; - height: 100px; - overflow: auto; -} - -.EmojiPosition { - cursor: pointer; - position: absolute; - bottom: 20px; - right: 20px; - white-space: initial !important; -} - .editorScroller { min-height: 150px; border: 0; @@ -98,6 +77,7 @@ color: rgba(0, 0, 0, 0.38); pointer-events: none; } + .editor { flex: auto; position: relative; @@ -105,59 +85,6 @@ z-index: -1; } -.Emoji { - width: 24px; -} - -.Font { - line-height: 1.25; - font-weight: 400; - font-size: 16px; - font-family: 'Heebo', sans-serif; - color: #073f24; - text-transform: inherit !important; -} - -/* - Overriding draft-js mentions styles as per requirement -*/ -.mentionSuggestions { - composes: Font; - background: #fff; - border-radius: 8px; - cursor: pointer; - display: flex; - flex-direction: column; - box-sizing: border-box; - transform-origin: 50% 0%; - transform: scaleY(0); - box-shadow: 0px 6px 6px 0px lightgray; - z-index: 100; - overflow-y: auto; - max-height: 360px; -} - -.mentionSuggestionsEntry { - padding: 7px 10px 3px 10px; - transition: background-color 0.4s cubic-bezier(0.27, 1.27, 0.48, 0.56); -} - -.mentionSuggestionsEntry:active { - background-color: #edf6f2; -} - -.mentionSuggestionsEntryFocused { - composes: mentionSuggestionsEntry; - background-color: #edf6f2; -} - -.mentionSuggestionsEntryText, -.mentionSuggestionsEntryTitle { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - .editorPlaceholder { color: #999; overflow: hidden; @@ -171,13 +98,9 @@ pointer-events: none; } -/* .MentionMenu { - background: #fff; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.3); - border-radius: 8px; - position: fixed; -} */ - +/* + Overriding draft-js mentions styles as per requirement +*/ .MentionMenu { padding: 0; background: #fff; @@ -189,9 +112,6 @@ border-radius: 8px; max-height: 200px; overflow-y: scroll; -} - -.MentionMenu { -ms-overflow-style: none; scrollbar-width: none; } @@ -210,7 +130,6 @@ } .MentionMenu li { - /* margin: 0 8px 0 8px; */ padding: 8px; color: #050505; cursor: pointer; @@ -253,8 +172,6 @@ .MentionMenu li .icon { display: flex; - /* width: 20px; */ - /* height: 20px; */ user-select: none; margin-right: 8px; line-height: 16px; @@ -262,11 +179,3 @@ background-repeat: no-repeat; background-position: center; } - -.component-picker-menu { - width: 200px; -} - -.mentions-menu { - width: 250px; -} diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index 584d101b6..feb33620b 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -43,7 +43,7 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP const { field, form, picker, placeholder, onChange } = props; const mentions = props.inputProp?.suggestions || []; const suggestions = { - '@': mentions, + '@': mentions?.map((mention: string) => mention?.split('@')[1]), }; const params = useParams(); @@ -147,7 +147,6 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP ErrorBoundary={LexicalErrorBoundary} /> - {/* {' '} */} Date: Mon, 12 Feb 2024 01:01:30 +0530 Subject: [PATCH 16/36] updated test cases --- src/components/UI/Form/EmojiInput/EmojiInput.module.css | 2 +- src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 3 --- src/containers/InteractiveMessage/InteractiveMessage.test.tsx | 1 - src/containers/Template/Editor.module.css | 3 --- src/containers/Template/Editor.tsx | 2 +- src/matchMediMock.ts | 4 ++-- 6 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.module.css b/src/components/UI/Form/EmojiInput/EmojiInput.module.css index 8bcca3089..869df36f8 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.module.css +++ b/src/components/UI/Form/EmojiInput/EmojiInput.module.css @@ -20,7 +20,7 @@ } /* - Overriding draft-js mentions styles as per requirement + Overriding lexical mentions styles as per requirement */ .mentionSuggestions { composes: Font; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index fa90f55e1..14c5cc022 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -75,9 +75,6 @@ export const WhatsAppEditor = ({ ) { sendMessage(editor.getRootElement()?.textContent); } - { - sendMessage(editor?.getRootElement()?.textContent); - } } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { formatter = 'bold'; } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { diff --git a/src/containers/InteractiveMessage/InteractiveMessage.test.tsx b/src/containers/InteractiveMessage/InteractiveMessage.test.tsx index 4c8034d8e..d1c7c3a5b 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.test.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.test.tsx @@ -148,7 +148,6 @@ test('it renders empty interactive form', async () => { await waitFor(() => { // Adding list data - // [title, lexicalEditor, quickReply1, quickReply2, , attachmentUrl] const [, , header, listTitle, listItemTitle, listItemDesc] = screen.getAllByRole('textbox'); expect(header).toBeInTheDocument(); diff --git a/src/containers/Template/Editor.module.css b/src/containers/Template/Editor.module.css index d4b19eb00..0d26b9a3e 100644 --- a/src/containers/Template/Editor.module.css +++ b/src/containers/Template/Editor.module.css @@ -4,12 +4,9 @@ line-height: 1 !important; font-size: 12px !important; margin-top: 4px !important; - /* position: absolute; */ - /* bottom: 0; */ } .Editor { - /* margin-bottom: 1rem; */ position: relative; border: 2px solid rgba(0, 0, 0, 0.23); border-radius: 12px; diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index feb33620b..f7103189a 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -43,7 +43,7 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP const { field, form, picker, placeholder, onChange } = props; const mentions = props.inputProp?.suggestions || []; const suggestions = { - '@': mentions?.map((mention: string) => mention?.split('@')[1]), + '@': mentions?.map((mention: string) => mention.split('@')[1]), }; const params = useParams(); diff --git a/src/matchMediMock.ts b/src/matchMediMock.ts index a58eb6f09..eb6eb6524 100644 --- a/src/matchMediMock.ts +++ b/src/matchMediMock.ts @@ -4,8 +4,8 @@ Object.defineProperty(window, 'matchMedia', { matches: false, media: query, onchange: null, - addListener: vi.fn(), // deprecated - removeListener: vi.fn(), // deprecated + addListener: vi.fn(), + removeListener: vi.fn(), addEventListener: vi.fn(), removeEventListener: vi.fn(), dispatchEvent: vi.fn(), From 5d9352bb37fd5b1e2119bb97069047b4b39208b0 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Mon, 12 Feb 2024 01:20:03 +0530 Subject: [PATCH 17/36] test cases --- package.json | 3 --- src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 2 +- src/containers/Template/Editor.module.css | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9cbc7a754..0d44d80f6 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,6 @@ "@appsignal/plugin-window-events": "^1.0.20", "@appsignal/react": "^1.0.23", "@date-io/dayjs": "^3.0.0", - "@draft-js-plugins/editor": "^4.1.4", - "@draft-js-plugins/mention": "^5.2.2", "@emoji-mart/data": "^1.1.2", "@emoji-mart/react": "^1.1.1", "@emotion/react": "^11.11.3", @@ -33,7 +31,6 @@ "axios": "^1.6.7", "buffer": "^6.0.3", "dayjs": "^1.11.10", - "draft-js": "^0.11.7", "emoji-mart": "^5.5.2", "formik": "^2.4.5", "graphql": "^16.8.1", diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 973fee1d7..dfa48d43d 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -96,7 +96,7 @@ export const WhatsAppEditor = ({ }, COMMAND_PRIORITY_LOW ); - }, [editor, onChange]); + }, [editor]); const Placeholder = () => { return
Type a message...
; diff --git a/src/containers/Template/Editor.module.css b/src/containers/Template/Editor.module.css index 0d26b9a3e..68d307808 100644 --- a/src/containers/Template/Editor.module.css +++ b/src/containers/Template/Editor.module.css @@ -96,7 +96,7 @@ } /* - Overriding draft-js mentions styles as per requirement + Overriding lexical mentions styles as per requirement */ .MentionMenu { padding: 0; From 7a66e8d17c2bb3b41a4997ba216bb47d2cbc2c9a Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Mon, 12 Feb 2024 10:36:08 +0530 Subject: [PATCH 18/36] fixed a minor issue --- src/containers/Form/FormLayout.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/containers/Form/FormLayout.tsx b/src/containers/Form/FormLayout.tsx index e8cfd94b9..4ad661f31 100644 --- a/src/containers/Form/FormLayout.tsx +++ b/src/containers/Form/FormLayout.tsx @@ -395,9 +395,6 @@ export const FormLayout = ({ if (field.additionalState) { additionalState(payload[field.additionalState]); } - if (field.convertToWhatsApp && payload[field.name]) { - payload[field.name] = payload[field.name]; - } if (field.skipPayload) { delete payload[field.name]; } From 0155a3c4189cd9aeda0a00a14e6cfdc9a306159a Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Tue, 13 Feb 2024 11:09:14 +0530 Subject: [PATCH 19/36] updated data test id for test cases --- src/components/UI/Form/EmojiInput/EmojiInput.test.tsx | 6 +++--- src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 2 +- .../Chat/ChatMessages/ChatInput/ChatInput.module.css | 2 +- src/containers/Chat/ChatMessages/ChatMessages.tsx | 2 +- src/containers/Template/Editor.tsx | 3 +-- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx index d1dc2b8f3..f2bdad9f5 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx @@ -1,5 +1,5 @@ import '../../../../matchMediMock'; -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import { EmojiInput } from './EmojiInput'; import userEvent from '@testing-library/user-event'; @@ -28,9 +28,9 @@ const wrapper = ( rows={10} /> ); -it('renders component', () => { +it.only('renders component', () => { const { getByTestId } = render(wrapper); - expect(getByTestId('editor')).toBeInTheDocument(); + expect(getByTestId('editor-input')).toBeInTheDocument(); }); it('should have a emoji picker', () => { diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index dfa48d43d..aee1a6bf1 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -103,7 +103,7 @@ export const WhatsAppEditor = ({ }; return ( -
+
} diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.module.css b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.module.css index c8e6bfb0e..9037a8a9d 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.module.css +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.module.css @@ -2,7 +2,7 @@ padding-top: 15px; position: absolute; bottom: 15px; - + background-color: #f9f7f4; left: 0; right: 0; margin: auto; diff --git a/src/containers/Chat/ChatMessages/ChatMessages.tsx b/src/containers/Chat/ChatMessages/ChatMessages.tsx index 09c883b3e..e8c490874 100644 --- a/src/containers/Chat/ChatMessages/ChatMessages.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessages.tsx @@ -593,7 +593,7 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe messageListContainer = ( diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index 58a6d97ba..15968c75c 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -136,13 +136,12 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP
} contentEditable={
From 99023be259a726ca9e3d3135636806daa45c33c5 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Tue, 13 Feb 2024 11:26:44 +0530 Subject: [PATCH 20/36] updated data test id for test cases --- src/common/RichEditor.tsx | 2 ++ src/components/UI/Form/EmojiInput/EmojiInput.test.tsx | 2 +- .../UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx | 1 - .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 11 +++-------- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/common/RichEditor.tsx b/src/common/RichEditor.tsx index 62051c312..7711b4a94 100644 --- a/src/common/RichEditor.tsx +++ b/src/common/RichEditor.tsx @@ -7,6 +7,8 @@ import { UrlMatcher } from 'interweave-autolink'; const regexForLink = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi; +export const getTextContent = (editorState: any) => editorState.getRootElement().textContent; + const isAlphanumeric = (c: any) => { const x = c.charCodeAt(); return (x >= 65 && x <= 90) || (x >= 97 && x <= 122) || (x >= 48 && x <= 57); diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx index f2bdad9f5..f028d50bf 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx @@ -1,5 +1,5 @@ import '../../../../matchMediMock'; -import { render, screen } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { EmojiInput } from './EmojiInput'; import userEvent from '@testing-library/user-event'; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx index 467754328..163e3e07e 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx @@ -55,7 +55,6 @@ describe('', () => { ); const editor = screen.getByTestId('editor'); - console.log(editor); await userEvent.click(editor); await userEvent.tab(); diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index aee1a6bf1..802b529e9 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -15,6 +15,7 @@ import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; import { useResizeDetector } from 'react-resize-detector'; import styles from './WhatsAppEditor.module.css'; +import { getTextContent } from 'common/RichEditor'; interface WhatsAppEditorProps { handleHeightChange(newHeight: number): void; @@ -69,14 +70,8 @@ export const WhatsAppEditor = ({ let formatter = ''; if (event.code === 'Enter' && !readOnly) { event.preventDefault(); - if ( - editor && - editor.getRootElement() && - editor.getRootElement()!.textContent && - typeof editor.getRootElement()!.textContent === 'string' - ) { - sendMessage(editor.getRootElement()?.textContent); - } + let textMessage = getTextContent(editor); + sendMessage(textMessage); } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { formatter = 'bold'; } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { From dbcb624f6ad7c4937fe402afb8b84138e673c92c Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Tue, 13 Feb 2024 12:07:45 +0530 Subject: [PATCH 21/36] updated data test id for test cases --- src/components/UI/Form/EmojiInput/EmojiInput.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx index f028d50bf..cdb03e422 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx @@ -28,7 +28,7 @@ const wrapper = ( rows={10} /> ); -it.only('renders component', () => { +it('renders component', () => { const { getByTestId } = render(wrapper); expect(getByTestId('editor-input')).toBeInTheDocument(); }); From 545add7cf1c55b50f4637df5a61b219a167c008d Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 16 Feb 2024 20:20:44 +0530 Subject: [PATCH 22/36] fixed minor bugs --- src/common/RichEditor.tsx | 2 +- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 21 ++++++++----------- .../Chat/ChatMessages/ChatInput/ChatInput.tsx | 11 +++++----- src/containers/Template/Editor.module.css | 9 ++++---- src/containers/Template/Editor.tsx | 6 ++++++ 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/common/RichEditor.tsx b/src/common/RichEditor.tsx index 7711b4a94..2ca775677 100644 --- a/src/common/RichEditor.tsx +++ b/src/common/RichEditor.tsx @@ -7,7 +7,7 @@ import { UrlMatcher } from 'interweave-autolink'; const regexForLink = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi; -export const getTextContent = (editorState: any) => editorState.getRootElement().textContent; +export const getTextContent = (editorState: any) => editorState?.getRootElement()?.textContent; const isAlphanumeric = (c: any) => { const x = c.charCodeAt(); diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 802b529e9..355385e36 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -20,12 +20,10 @@ import { getTextContent } from 'common/RichEditor'; interface WhatsAppEditorProps { handleHeightChange(newHeight: number): void; sendMessage(message: any): void; - setEditorState(editorState: any): void; readOnly?: boolean; } export const WhatsAppEditor = ({ - setEditorState, sendMessage, handleHeightChange, readOnly = false, @@ -42,13 +40,6 @@ export const WhatsAppEditor = ({ onResize, }); - const onChange = (editorState: any) => { - editorState.read(() => { - const root = $getRoot(); - setEditorState(root.getTextContent()); - }); - }; - const handleFormatting = (text: string, formatter: string) => { switch (formatter) { case 'bold': @@ -68,10 +59,11 @@ export const WhatsAppEditor = ({ (event: KeyboardEvent) => { // Handle event here let formatter = ''; - if (event.code === 'Enter' && !readOnly) { + if (event.code === 'Enter' && !event.shiftKey) { event.preventDefault(); let textMessage = getTextContent(editor); sendMessage(textMessage); + return true; } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { formatter = 'bold'; } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { @@ -102,11 +94,16 @@ export const WhatsAppEditor = ({ } - contentEditable={} + contentEditable={ + + } ErrorBoundary={LexicalErrorBoundary} /> -
); }; diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index c95215e3a..c324d0c87 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -30,6 +30,7 @@ import { $getSelection, $isRangeSelection, } from 'lexical'; +import { getTextContent } from 'common/RichEditor'; export interface ChatInputProps { onSendMessage( @@ -57,7 +58,6 @@ export const ChatInput = ({ isCollection, lastMessageTime, }: ChatInputProps) => { - const [editorState, setEditorState] = useState(''); const [selectedTab, setSelectedTab] = useState(''); const [open, setOpen] = useState(false); const [searchVal, setSearchVal] = useState(''); @@ -87,7 +87,6 @@ export const ChatInput = ({ const resetVariable = () => { setUpdatedEditorState(undefined); - setEditorState(''); setSelectedTemplate(undefined); setInteractiveMessageContent({}); setVariableParam([]); @@ -249,7 +248,6 @@ export const ChatInput = ({ setSelectedTemplate(obj); // Conversion from HTML text to EditorState - setEditorState(messageBody); editor.update(() => { const root = $getRoot(); const paragraph = $createParagraphNode(); @@ -433,7 +431,6 @@ export const ChatInput = ({ }`} > { - submitMessage(editorState); + submitMessage(getTextContent(editor)); }} - disabled={(!editorState && !attachmentAdded && !recordedAudio) || uploading} + disabled={ + (!getTextContent(editor) && !attachmentAdded && !recordedAudio) || uploading + } > diff --git a/src/containers/Template/Editor.module.css b/src/containers/Template/Editor.module.css index 68d307808..7e47af5e2 100644 --- a/src/containers/Template/Editor.module.css +++ b/src/containers/Template/Editor.module.css @@ -12,7 +12,7 @@ border-radius: 12px; height: 10rem; position: relative; - padding: 0 1rem; + padding: 0 1rem 1rem 1rem; position: relative; display: block; border-bottom-left-radius: 10px; @@ -33,7 +33,6 @@ .EditorInput { resize: none; font-size: 16px; - overflow: auto; width: 100%; min-height: 40px; height: 100%; @@ -52,12 +51,13 @@ } .editorScroller { - min-height: 150px; border: 0; display: flex; position: relative; outline: 0; z-index: 0; + height: 100%; + overflow: auto; } .disabled { @@ -66,13 +66,12 @@ border-radius: 12px; height: 10rem; position: relative; - padding: 0 1rem; + padding: 0 1rem 1rem 1rem; position: relative; display: block; border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; color: rgba(0, 0, 0, 0.38); - pointer-events: none; } .editor { diff --git a/src/containers/Template/Editor.tsx b/src/containers/Template/Editor.tsx index 15968c75c..8b1bc11ae 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/containers/Template/Editor.tsx @@ -122,6 +122,12 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP ); }, [editor]); + useEffect(() => { + if (disabled) { + editor.setEditable(false); + } + }, [disabled]); + const handleChange = (editorState: any) => { editorState.read(() => { const root = $getRoot(); From 15366102f62300b9890e9adc4e5a2f6884cbb6d9 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Fri, 16 Feb 2024 21:02:51 +0530 Subject: [PATCH 23/36] test cases --- .../UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx | 6 ++++-- src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 9 +-------- .../Chat/ChatMessages/ChatInput/ChatInput.test.tsx | 6 +++++- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx index 163e3e07e..97632146b 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx @@ -38,8 +38,10 @@ describe('', () => { ); await userEvent.click(getByTestId('editor')); - await userEvent.keyboard('10'); - expect(setEditorState).toHaveBeenCalled(); + await userEvent.tab(); + await fireEvent.input(getByTestId('editor'), { data: 'test' }); + + expect(getByTestId('editor')).toHaveTextContent('test'); }); test('text is changed in lexical editor', async () => { diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 355385e36..3f3a9a1f8 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -1,14 +1,7 @@ import { useCallback, useEffect } from 'react'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; -import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; -import { - $getSelection, - $createTextNode, - $getRoot, - KEY_DOWN_COMMAND, - COMMAND_PRIORITY_LOW, -} from 'lexical'; +import { $getSelection, $createTextNode, KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW } from 'lexical'; import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx index 88a58de1c..65e8d2f67 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx @@ -151,15 +151,19 @@ describe('', () => { }); }); - test('send an interactive message', async () => { + test.only('send an interactive message', async () => { const { getAllByTestId, getByTestId } = render(chatInput); const interactiveMessages = getAllByTestId('shortcutButton')[2]; fireEvent.click(interactiveMessages); await waitFor(() => { const listItem = getAllByTestId('templateItem')[0]; + console.log('DDD', getAllByTestId('templateItem')[0].outerHTML); + fireEvent.click(listItem); }); fireEvent.click(getByTestId('sendButton')); + console.log(inputSubmitted); + expect(inputSubmitted).toBe(true); }); From 65d74fea8b65cf997b74edc9bfeac7bb85ff08e0 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Sat, 17 Feb 2024 23:43:58 +0530 Subject: [PATCH 24/36] fixed minor issues and test cases --- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 29 +++-- .../ChatMessages/ChatInput/ChatInput.test.tsx | 7 +- .../Chat/ChatMessages/ChatInput/ChatInput.tsx | 17 ++- yarn.lock | 110 +----------------- 4 files changed, 34 insertions(+), 129 deletions(-) diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index 3f3a9a1f8..b05e2c1d5 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -1,8 +1,16 @@ import { useCallback, useEffect } from 'react'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; -import { $getSelection, $createTextNode, KEY_DOWN_COMMAND, COMMAND_PRIORITY_LOW } from 'lexical'; +import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; +import { + $getSelection, + $createTextNode, + $getRoot, + KEY_DOWN_COMMAND, + COMMAND_PRIORITY_LOW, +} from 'lexical'; import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; +import { ClearEditorPlugin } from '@lexical/react/LexicalClearEditorPlugin'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; import { useResizeDetector } from 'react-resize-detector'; @@ -13,10 +21,12 @@ import { getTextContent } from 'common/RichEditor'; interface WhatsAppEditorProps { handleHeightChange(newHeight: number): void; sendMessage(message: any): void; + setEditorState(editorState: any): void; readOnly?: boolean; } export const WhatsAppEditor = ({ + setEditorState, sendMessage, handleHeightChange, readOnly = false, @@ -33,6 +43,13 @@ export const WhatsAppEditor = ({ onResize, }); + const onChange = (editorState: any) => { + editorState.read(() => { + const root = $getRoot(); + setEditorState(root.getTextContent()); + }); + }; + const handleFormatting = (text: string, formatter: string) => { switch (formatter) { case 'bold': @@ -87,16 +104,12 @@ export const WhatsAppEditor = ({ } - contentEditable={ - - } + contentEditable={} ErrorBoundary={LexicalErrorBoundary} /> + +
); }; diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx index 65e8d2f67..12bb79c36 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx @@ -151,19 +151,16 @@ describe('', () => { }); }); - test.only('send an interactive message', async () => { + test('send an interactive message', async () => { const { getAllByTestId, getByTestId } = render(chatInput); const interactiveMessages = getAllByTestId('shortcutButton')[2]; fireEvent.click(interactiveMessages); await waitFor(() => { - const listItem = getAllByTestId('templateItem')[0]; - console.log('DDD', getAllByTestId('templateItem')[0].outerHTML); + const listItem = getAllByTestId('templateItem')[1]; fireEvent.click(listItem); }); fireEvent.click(getByTestId('sendButton')); - console.log(inputSubmitted); - expect(inputSubmitted).toBe(true); }); diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index c324d0c87..dee38deaf 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -29,8 +29,8 @@ import { $getRoot, $getSelection, $isRangeSelection, + CLEAR_EDITOR_COMMAND, } from 'lexical'; -import { getTextContent } from 'common/RichEditor'; export interface ChatInputProps { onSendMessage( @@ -58,6 +58,7 @@ export const ChatInput = ({ isCollection, lastMessageTime, }: ChatInputProps) => { + const [editorState, setEditorState] = useState(''); const [selectedTab, setSelectedTab] = useState(''); const [open, setOpen] = useState(false); const [searchVal, setSearchVal] = useState(''); @@ -87,6 +88,7 @@ export const ChatInput = ({ const resetVariable = () => { setUpdatedEditorState(undefined); + setEditorState(''); setSelectedTemplate(undefined); setInteractiveMessageContent({}); setVariableParam([]); @@ -195,10 +197,7 @@ export const ChatInput = ({ } // Resetting the EditorState - editor.update(() => { - const root = $getRoot(); - root.clear(); - }); + editor.dispatchCommand(CLEAR_EDITOR_COMMAND, undefined); editor.focus(); }; @@ -248,6 +247,7 @@ export const ChatInput = ({ setSelectedTemplate(obj); // Conversion from HTML text to EditorState + setEditorState(messageBody); editor.update(() => { const root = $getRoot(); const paragraph = $createParagraphNode(); @@ -431,6 +431,7 @@ export const ChatInput = ({ }`} > { - submitMessage(getTextContent(editor)); + submitMessage(editorState); }} - disabled={ - (!getTextContent(editor) && !attachmentAdded && !recordedAudio) || uploading - } + disabled={(!editorState && !attachmentAdded && !recordedAudio) || uploading} > diff --git a/yarn.lock b/yarn.lock index 8e6fff47f..be3c73660 100644 --- a/yarn.lock +++ b/yarn.lock @@ -351,28 +351,6 @@ dependencies: "@date-io/core" "^3.0.0" -"@draft-js-plugins/editor@^4.1.4": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@draft-js-plugins/editor/-/editor-4.1.4.tgz#456e01b032b8ef44f0c77ea777aa3c44172de892" - integrity sha512-NlE1AIsPPfmdn+JIwwmcAm18FgwJ9/A55+2VXf3US3PmITJVL+y9VORCwLbGh2sb0RXvgFOIbqs8pPAOe8F8WQ== - dependencies: - immutable "~3.7.4" - prop-types "^15.8.1" - -"@draft-js-plugins/mention@^5.2.2": - version "5.2.2" - resolved "https://registry.yarnpkg.com/@draft-js-plugins/mention/-/mention-5.2.2.tgz#3ed6fe248fc931f28ba494a6887fc156b90b6059" - integrity sha512-CoympO4FTBHD11mb+lSdD2KvtvwvHeUl+YDUymgtQBncZI4TKNKwZji60JdfNoGFQzDu87QkwKzv3iG8XQmNzA== - dependencies: - "@popperjs/core" "^2.11.8" - "@types/lodash" "^4.14.195" - clsx "^1.2.1" - immutable "~3.7.4" - lodash "^4.17.21" - lodash-es "^4.17.21" - prop-types "^15.8.1" - react-popper "^2.3.0" - "@emoji-mart/data@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@emoji-mart/data/-/data-1.1.2.tgz#777c976f8f143df47cbb23a7077c9ca9fe5fc513" @@ -1454,11 +1432,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/lodash@^4.14.195": - version "4.14.202" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" - integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== - "@types/minimatch@^3.0.3": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -1890,11 +1863,6 @@ arraybuffer.prototype.slice@^1.0.2: is-array-buffer "^3.0.2" is-shared-array-buffer "^1.0.2" -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== - assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -2210,7 +2178,7 @@ clone@^2.1.2: resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== -clsx@^1.1.1, clsx@^1.2.1: +clsx@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== @@ -2316,11 +2284,6 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -core-js@^3.6.4: - version "3.34.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.34.0.tgz#5705e6ad5982678612e96987d05b27c6c7c274a5" - integrity sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag== - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -2352,13 +2315,6 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-fetch@^3.0.4: - version "3.1.8" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" - integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== - dependencies: - node-fetch "^2.6.12" - cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -2597,15 +2553,6 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" -draft-js@^0.11.7: - version "0.11.7" - resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.11.7.tgz#be293aaa255c46d8a6647f3860aa4c178484a206" - integrity sha512-ne7yFfN4sEL82QPQEn80xnADR8/Q6ALVworbC5UOSzOvjffmYfFsr3xSZtxbIirti14R7Y33EZC5rivpLgIbsg== - dependencies: - fbjs "^2.0.0" - immutable "~3.7.4" - object-assign "^4.1.1" - duplexify@^4.1.1: version "4.1.2" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" @@ -3097,25 +3044,6 @@ fastq@^1.13.0, fastq@^1.6.0: dependencies: reusify "^1.0.4" -fbjs-css-vars@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" - integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== - -fbjs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-2.0.0.tgz#01fb812138d7e31831ed3e374afe27b9169ef442" - integrity sha512-8XA8ny9ifxrAWlyhAbexXcs3rRMtxWcs3M0lctLfB49jRDHiaxj+Mo0XxbwE7nKZYzgCFoq64FS+WFd4IycPPQ== - dependencies: - core-js "^3.6.4" - cross-fetch "^3.0.4" - fbjs-css-vars "^1.0.0" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.18" - fflate@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.1.tgz#1ed92270674d2ad3c73f077cd0acf26486dae6c9" @@ -4137,7 +4065,7 @@ logflare-transport-core@^0.3.3: resolved "https://registry.yarnpkg.com/logflare-transport-core/-/logflare-transport-core-0.3.3.tgz#dade63f6b414b7d01727825ce0ccb830ed6f0f7e" integrity sha512-n82NsRVWvlaa3jd9QQ8rDroCjCJcIamQOlarLDBou9RsF0QaRv39rduy0ToPmlGQn1OPZBwlsv+R36lXupSmVQ== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -4357,7 +4285,7 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-fetch@^2.6.1, node-fetch@^2.6.12: +node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -4743,13 +4671,6 @@ promise-map-series@^0.3.0: resolved "https://registry.yarnpkg.com/promise-map-series/-/promise-map-series-0.3.0.tgz#41873ca3652bb7a042b387d538552da9b576f8a1" integrity sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA== -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" @@ -4939,14 +4860,6 @@ react-player@^2.14.1: prop-types "^15.7.2" react-fast-compare "^3.0.1" -react-popper@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" - integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q== - dependencies: - react-fast-compare "^3.0.1" - warning "^4.0.2" - react-refresh@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" @@ -5359,11 +5272,6 @@ set-function-name@^2.0.0, set-function-name@^2.0.1: functions-have-names "^1.2.3" has-property-descriptors "^1.0.0" -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -5910,11 +5818,6 @@ typescript@^5.0.4, typescript@^5.3.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== -ua-parser-js@^0.7.18: - version "0.7.37" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.37.tgz#e464e66dac2d33a7a1251d7d7a99d6157ec27832" - integrity sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA== - ufo@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.2.tgz#c7d719d0628a1c80c006d2240e0d169f6e3c0496" @@ -6245,13 +6148,6 @@ walk-sync@^2.2.0: matcher-collection "^2.0.0" minimatch "^3.0.4" -warning@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" - integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== - dependencies: - loose-envify "^1.0.0" - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" From 7e9f6b76a63015bbcb8bc8135308524b540510fd Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Sun, 18 Feb 2024 01:13:20 +0530 Subject: [PATCH 25/36] mentions plugins bugs fixed --- .../UI/Form/EmojiInput}/Editor.module.css | 24 +++---------------- .../UI/Form/EmojiInput}/Editor.tsx | 11 ++++++++- .../UI/Form/EmojiInput/EmojiInput.tsx | 8 ++----- .../WhatsAppEditor/WhatsAppEditor.module.css | 21 +++------------- 4 files changed, 18 insertions(+), 46 deletions(-) rename src/{containers/Template => components/UI/Form/EmojiInput}/Editor.module.css (86%) rename src/{containers/Template => components/UI/Form/EmojiInput}/Editor.tsx (96%) diff --git a/src/containers/Template/Editor.module.css b/src/components/UI/Form/EmojiInput/Editor.module.css similarity index 86% rename from src/containers/Template/Editor.module.css rename to src/components/UI/Form/EmojiInput/Editor.module.css index 7e47af5e2..ad3d5b220 100644 --- a/src/containers/Template/Editor.module.css +++ b/src/components/UI/Form/EmojiInput/Editor.module.css @@ -102,13 +102,12 @@ background: #fff; box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.3); border-radius: 8px; - position: fixed; list-style: none; margin: 0; - border-radius: 8px; max-height: 200px; overflow-y: scroll; -ms-overflow-style: none; + width: 250px; scrollbar-width: none; } @@ -121,8 +120,8 @@ border-radius: 8px; } -.MentionMenu ul li.selected { - background: #eee; +.Selected { + background: #eee !important; } .MentionMenu li { @@ -158,20 +157,3 @@ .MentionMenu li:hover { background-color: #eee; } - -.MentionMenu li .text { - display: flex; - line-height: 20px; - flex-grow: 1; - min-width: 150px; -} - -.MentionMenu li .icon { - display: flex; - user-select: none; - margin-right: 8px; - line-height: 16px; - background-size: contain; - background-repeat: no-repeat; - background-position: center; -} diff --git a/src/containers/Template/Editor.tsx b/src/components/UI/Form/EmojiInput/Editor.tsx similarity index 96% rename from src/containers/Template/Editor.tsx rename to src/components/UI/Form/EmojiInput/Editor.tsx index 8b1bc11ae..e01b9651d 100644 --- a/src/containers/Template/Editor.tsx +++ b/src/components/UI/Form/EmojiInput/Editor.tsx @@ -181,5 +181,14 @@ const CustomMenu = forwardRef( ); const CustomMenuItem = forwardRef( - ({ selected, item, ...props }, ref) =>
  • + ({ selected, item, ...props }, ref) => { + return ( +
  • + ); + } ); diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index 661ad196c..b6133fb12 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -1,16 +1,12 @@ import { useState } from 'react'; import { InputAdornment, IconButton, ClickAwayListener } from '@mui/material'; import { EmojiPicker } from 'components/UI/EmojiPicker/EmojiPicker'; -import { Editor } from 'containers/Template/Editor'; +import { Editor } from './Editor'; import Styles from './EmojiInput.module.css'; import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { BeautifulMentionNode } from 'lexical-beautiful-mentions'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; -import { - $createTextNode, - $getSelection, - $isRangeSelection, -} from 'lexical'; +import { $createTextNode, $getSelection, $isRangeSelection } from 'lexical'; export interface EmojiInputProps { field: any; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css index 3911a3262..35fd91a29 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.module.css @@ -2,22 +2,7 @@ overflow: auto; width: 100%; min-height: 40px; -} - -.Editor :global(.public-DraftEditor-content) > div { - padding-top: 10px; - padding-bottom: 10px; - color: #073f24; - font-size: 16px; - line-height: 1.25; -} - -.Editor :global(.public-DraftEditorPlaceholder-inner) { - padding-top: 10px; - margin-bottom: -32px; - pointer-events: none; - color: #93a29b; - font-size: 16px; + position: relative; } /* TODO: Override emoji-mart-emoji font-size to make it medium. */ @@ -46,8 +31,8 @@ span.emoji-mart-emoji { overflow: hidden; position: absolute; text-overflow: ellipsis; - top: 45px; - left: 35px; + top: 22px; + left: 0px; font-size: 15px; user-select: none; display: inline-block; From f0458de8dd078380db862fe31451ce2b91e717ff Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Sun, 18 Feb 2024 02:25:30 +0530 Subject: [PATCH 26/36] test cases --- .../UI/Form/EmojiInput/Editor.test.tsx | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/components/UI/Form/EmojiInput/Editor.test.tsx diff --git a/src/components/UI/Form/EmojiInput/Editor.test.tsx b/src/components/UI/Form/EmojiInput/Editor.test.tsx new file mode 100644 index 000000000..3f33afe24 --- /dev/null +++ b/src/components/UI/Form/EmojiInput/Editor.test.tsx @@ -0,0 +1,65 @@ +import '../../../../matchMediMock'; +import { act, fireEvent, render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { Editor } from './Editor'; +import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { BeautifulMentionNode } from 'lexical-beautiful-mentions'; + +const setFieldValueMock = vi.fn(); + +const mockIntersectionObserver = class { + constructor() {} + observe() {} + unobserve() {} + disconnect() {} +}; + +const lexicalChange = vi.fn; + +(window as any).IntersectionObserver = mockIntersectionObserver; + +const wrapper = ( + console.log(error), + nodes: [BeautifulMentionNode], + }} + > + {} }} + placeholder={''} + onChange={lexicalChange} + /> + +); + +it('should render lexical editor', () => { + const { getByTestId } = render(wrapper); + + expect(getByTestId('editor-body')).toBeInTheDocument(); +}); + +it('shoul open contact variables dropdown', async () => { + const { getByTestId } = render(wrapper); + const editor = getByTestId('editor-body'); + + await userEvent.click(editor); + await userEvent.tab(); + userEvent.keyboard('ddd'); + // await fireEvent.input(editor, { data: 'this text is bold' }); + screen.debug(); +}); + +// it('should render make text bold', async () => { +// const { getByTestId } = render(wrapper); +// const editor = getByTestId('editor-body'); +// await userEvent.click(editor); +// // await userEvent.keyboard('this text is bold'); +// await userEvent.tab(); +// act(async () => { +// await fireEvent.input(editor, { data: 'this text is bold' }); +// }); +// screen.debug(); +// expect(getByTestId('editor-body')).toBeInTheDocument(); +// }); From 820e8618853f66a2dd27b26ce4f7af2f79996a4d Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Thu, 22 Feb 2024 14:34:21 +0530 Subject: [PATCH 27/36] resolved changes --- src/App.test.tsx | 1 + src/common/LexicalWrapper.tsx | 20 +++ src/common/RichEditor.tsx | 25 ++++ .../UI/Form/EmojiInput/Editor.test.tsx | 16 +-- src/components/UI/Form/EmojiInput/Editor.tsx | 47 +------ .../UI/Form/EmojiInput/EmojiInput.test.tsx | 2 +- .../UI/Form/EmojiInput/EmojiInput.tsx | 23 ++-- .../WhatsAppEditor/WhatsAppEditor.test.tsx | 30 ++--- .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 30 ++--- .../UI/MessageDialog/MessageDialog.test.tsx | 12 +- .../UI/MessageDialog/MessageDialog.tsx | 12 +- src/containers/Chat/Chat.test.tsx | 1 + .../ConversationList.test.tsx | 1 + .../Chat/ChatInterface/ChatInterface.test.tsx | 1 + .../ChatInput/ChatInput.module.css | 6 +- .../ChatMessages/ChatInput/ChatInput.test.tsx | 57 +++------ .../Chat/ChatMessages/ChatInput/ChatInput.tsx | 13 +- .../Chat/ChatMessages/ChatMessages.module.css | 10 ++ .../Chat/ChatMessages/ChatMessages.test.tsx | 3 +- .../Chat/ChatMessages/ChatMessages.tsx | 119 ++++++++---------- .../InteractiveMessage.test.tsx | 2 +- .../InteractiveMessage/InteractiveMessage.tsx | 6 + src/containers/Template/Form/HSM/HSM.test.tsx | 2 +- src/containers/Template/Form/HSM/HSM.tsx | 1 + .../Form/SpeedSend/SpeedSend.test.tsx | 15 +-- .../Template/Form/Template.test.tsx | 2 +- src/containers/Template/Form/Template.tsx | 1 + src/{matchMediMock.ts => matchMediaMock.ts} | 0 .../AuthenticatedRoute.test.tsx | 1 + ....timestamp-1708584423070-641d506fb9214.mjs | 115 +++++++++++++++++ 30 files changed, 312 insertions(+), 262 deletions(-) create mode 100644 src/common/LexicalWrapper.tsx rename src/{matchMediMock.ts => matchMediaMock.ts} (100%) create mode 100644 vite.config.ts.timestamp-1708584423070-641d506fb9214.mjs diff --git a/src/App.test.tsx b/src/App.test.tsx index b13876d04..f76a56255 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,3 +1,4 @@ +import './matchMediaMock'; import { MemoryRouter } from 'react-router-dom'; import { MockedProvider } from '@apollo/client/testing'; import { waitFor, render } from '@testing-library/react'; diff --git a/src/common/LexicalWrapper.tsx b/src/common/LexicalWrapper.tsx new file mode 100644 index 000000000..69ef86a4f --- /dev/null +++ b/src/common/LexicalWrapper.tsx @@ -0,0 +1,20 @@ +import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { BeautifulMentionNode } from 'lexical-beautiful-mentions'; + +interface LexicalWrapperProps { + children: any; +} + +export const LexicalWrapper = ({ children }: LexicalWrapperProps) => { + return ( + console.log(error), + nodes: [BeautifulMentionNode], + }} + > + {children} + + ); +}; diff --git a/src/common/RichEditor.tsx b/src/common/RichEditor.tsx index 2ca775677..7e2a06a86 100644 --- a/src/common/RichEditor.tsx +++ b/src/common/RichEditor.tsx @@ -9,6 +9,31 @@ const regexForLink = export const getTextContent = (editorState: any) => editorState?.getRootElement()?.textContent; +export const handleFormatterEvents = (event: KeyboardEvent) => { + if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { + return 'bold'; + } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { + return 'italic'; + } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyS') { + return 'strikethrough'; + } + + return ''; +}; + +export const handleFormatting = (text: string, formatter: string) => { + switch (formatter) { + case 'bold': + return `*${text}*`; + case 'italic': + return `_${text}_`; + case 'strikethrough': + return `~${text}~`; + default: + return text; + } +}; + const isAlphanumeric = (c: any) => { const x = c.charCodeAt(); return (x >= 65 && x <= 90) || (x >= 97 && x <= 122) || (x >= 48 && x <= 57); diff --git a/src/components/UI/Form/EmojiInput/Editor.test.tsx b/src/components/UI/Form/EmojiInput/Editor.test.tsx index 3f33afe24..1b26a8e23 100644 --- a/src/components/UI/Form/EmojiInput/Editor.test.tsx +++ b/src/components/UI/Form/EmojiInput/Editor.test.tsx @@ -1,9 +1,8 @@ -import '../../../../matchMediMock'; +import '../../../../matchMediaMock'; import { act, fireEvent, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { Editor } from './Editor'; -import { LexicalComposer } from '@lexical/react/LexicalComposer'; -import { BeautifulMentionNode } from 'lexical-beautiful-mentions'; +import { LexicalWrapper } from 'common/LexicalWrapper'; const setFieldValueMock = vi.fn(); @@ -19,19 +18,14 @@ const lexicalChange = vi.fn; (window as any).IntersectionObserver = mockIntersectionObserver; const wrapper = ( - console.log(error), - nodes: [BeautifulMentionNode], - }} - > + {} }} placeholder={''} onChange={lexicalChange} /> - + ); it('should render lexical editor', () => { diff --git a/src/components/UI/Form/EmojiInput/Editor.tsx b/src/components/UI/Form/EmojiInput/Editor.tsx index e01b9651d..d9366f2a3 100644 --- a/src/components/UI/Form/EmojiInput/Editor.tsx +++ b/src/components/UI/Form/EmojiInput/Editor.tsx @@ -22,28 +22,21 @@ import { BeautifulMentionsMenuItemProps, } from 'lexical-beautiful-mentions'; import { useParams } from 'react-router'; +import { handleFormatterEvents, handleFormatting } from 'common/RichEditor'; export interface EditorProps { - type?: any; field: { name: string; onChange?: any; value: any; onBlur: any }; disabled?: any; - label: string; form?: { touched: any; errors: any }; - placeholder: any; - rows?: number; - helperText?: any; + placeholder: string; + helperText?: string; picker?: any; - textArea?: boolean; - togglePassword?: boolean; - endAdornmentCallback?: any; - validate?: any; - endAdornment?: any; inputProp?: any; - translation?: string; onChange?: any; + isEditing: boolean; } -export const Editor = ({ textArea = false, disabled = false, ...props }: EditorProps) => { +export const Editor = ({ disabled = false, isEditing = false, ...props }: EditorProps) => { const [editorState, setEditorState] = useState(''); const { field, form, picker, placeholder, onChange } = props; const mentions = props.inputProp?.suggestions || []; @@ -51,12 +44,6 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP '@': mentions.map((mention: string) => mention?.split('@')[1]), }; const params = useParams(); - - let isEditing = false; - if (params.id) { - isEditing = true; - } - const [editor] = useLexicalComposerContext(); useEffect(() => { @@ -80,33 +67,11 @@ export const Editor = ({ textArea = false, disabled = false, ...props }: EditorP return

    {placeholder}

    ; }; - const handleFormatting = (text: string, formatter: string) => { - switch (formatter) { - case 'bold': - return `*${text}*`; - case 'italic': - return `_${text}_`; - case 'strikethrough': - return `~${text}~`; - default: - return text; - } - }; - useEffect(() => { return editor.registerCommand( KEY_DOWN_COMMAND, (event: KeyboardEvent) => { - let formatter = ''; - if (event.code === 'Enter') { - event.preventDefault(); // Prevent line break on enter - } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { - formatter = 'bold'; - } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { - formatter = 'italic'; - } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyS') { - formatter = 'strikethrough'; - } + let formatter = handleFormatterEvents(event); editor.update(() => { const selection = $getSelection(); diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx index cdb03e422..830e75462 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediMock'; +import '../../../../matchMediaMock'; import { render } from '@testing-library/react'; import { EmojiInput } from './EmojiInput'; import userEvent from '@testing-library/user-event'; diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.tsx index b6133fb12..6af42c145 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.tsx @@ -3,10 +3,9 @@ import { InputAdornment, IconButton, ClickAwayListener } from '@mui/material'; import { EmojiPicker } from 'components/UI/EmojiPicker/EmojiPicker'; import { Editor } from './Editor'; import Styles from './EmojiInput.module.css'; -import { LexicalComposer } from '@lexical/react/LexicalComposer'; -import { BeautifulMentionNode } from 'lexical-beautiful-mentions'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import { $createTextNode, $getSelection, $isRangeSelection } from 'lexical'; +import { LexicalWrapper } from 'common/LexicalWrapper'; export interface EmojiInputProps { field: any; @@ -19,6 +18,7 @@ export interface EmojiInputProps { handleBlur?: any; getEditorValue?: any; inputProp?: any; + isEditing?: boolean; } interface EmojiPickerProps { @@ -32,6 +32,7 @@ export const EmojiInput = ({ handleChange, getEditorValue, handleBlur, + isEditing = false, ...props }: EmojiInputProps) => { const [showEmojiPicker, setShowEmojiPicker] = useState(false); @@ -60,15 +61,15 @@ export const EmojiInput = ({ ); const input = ( - console.log(error), - nodes: [BeautifulMentionNode], - }} - > - - + + + ); return input; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx index 97632146b..9076aa818 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx @@ -1,9 +1,10 @@ +import '../../../../matchMediaMock'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { vi } from 'vitest'; import WhatsAppEditor from './WhatsAppEditor'; -import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { userEvent } from '@testing-library/user-event'; +import { LexicalWrapper } from 'common/LexicalWrapper'; const mockObserve = vi.fn(); global.ResizeObserver = vi.fn().mockImplementation(() => ({ @@ -27,14 +28,9 @@ describe('', () => { test('input change should trigger callBacks', async () => { const { getByTestId } = render( - console.log(error), - }} - > + - + ); await userEvent.click(getByTestId('editor')); @@ -46,14 +42,9 @@ describe('', () => { test('text is changed in lexical editor', async () => { const { getByTestId } = render( - console.log(error), - }} - > + - + ); const editor = screen.getByTestId('editor'); @@ -69,14 +60,9 @@ describe('', () => { test('resize observer event is called', async () => { render( - console.log(error), - }} - > + - + ); await waitFor(() => { expect(mockObserve).toHaveBeenCalled(); diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index b05e2c1d5..c42dc3f2b 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -16,10 +16,9 @@ import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; import { useResizeDetector } from 'react-resize-detector'; import styles from './WhatsAppEditor.module.css'; -import { getTextContent } from 'common/RichEditor'; +import { getTextContent, handleFormatterEvents, handleFormatting } from 'common/RichEditor'; interface WhatsAppEditorProps { - handleHeightChange(newHeight: number): void; sendMessage(message: any): void; setEditorState(editorState: any): void; readOnly?: boolean; @@ -28,19 +27,13 @@ interface WhatsAppEditorProps { export const WhatsAppEditor = ({ setEditorState, sendMessage, - handleHeightChange, readOnly = false, }: WhatsAppEditorProps) => { const [editor] = useLexicalComposerContext(); - const onResize = useCallback((height: any) => { - handleHeightChange(height - 40); - }, []); - const { ref } = useResizeDetector({ refreshMode: 'debounce', refreshRate: 1000, - onResize, }); const onChange = (editorState: any) => { @@ -50,18 +43,11 @@ export const WhatsAppEditor = ({ }); }; - const handleFormatting = (text: string, formatter: string) => { - switch (formatter) { - case 'bold': - return `*${text}*`; - case 'italic': - return `_${text}_`; - case 'strikethrough': - return `~${text}~`; - default: - return text; + useEffect(() => { + if (readOnly) { + editor.setEditable(false); } - }; + }, [readOnly]); useEffect(() => { return editor.registerCommand( @@ -74,10 +60,8 @@ export const WhatsAppEditor = ({ let textMessage = getTextContent(editor); sendMessage(textMessage); return true; - } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { - formatter = 'bold'; - } else if ((event.ctrlKey || event.metaKey) && event.code === 'KeyI') { - formatter = 'italic'; + } else { + formatter = handleFormatterEvents(event); } editor.update(() => { diff --git a/src/components/UI/MessageDialog/MessageDialog.test.tsx b/src/components/UI/MessageDialog/MessageDialog.test.tsx index 4c0e03f02..7c9524c68 100644 --- a/src/components/UI/MessageDialog/MessageDialog.test.tsx +++ b/src/components/UI/MessageDialog/MessageDialog.test.tsx @@ -1,9 +1,10 @@ +import '../../../matchMediaMock'; import { fireEvent, render } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import { MessageDialog } from './MessageDialog'; import { getAttachmentPermissionMock } from 'mocks/Attachment'; -import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { LexicalWrapper } from 'common/LexicalWrapper'; const handleClose = vi.fn(); @@ -14,14 +15,9 @@ const defaultProps = { }; const wrapper = ( - console.log(error), - }} - > + - + ); diff --git a/src/components/UI/MessageDialog/MessageDialog.tsx b/src/components/UI/MessageDialog/MessageDialog.tsx index 32330962e..4799db75e 100644 --- a/src/components/UI/MessageDialog/MessageDialog.tsx +++ b/src/components/UI/MessageDialog/MessageDialog.tsx @@ -3,7 +3,7 @@ import { Dialog, DialogContent } from '@mui/material'; import CrossDarkIcon from 'assets/images/icons/CrossDark.svg?react'; import ChatInput from 'containers/Chat/ChatMessages/ChatInput/ChatInput'; import styles from './MessageDialog.module.css'; -import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { LexicalWrapper } from 'common/LexicalWrapper'; export interface MessageDialogProps { title: string; @@ -22,20 +22,14 @@ export const MessageDialog = ({ title, onSendMessage, handleClose }: MessageDial
    {title}
    - console.log(error), - }} - > + {}} contactStatus="" contactBspStatus="SESSION_AND_HSM" additionalStyle={styles.ChatInput} /> - + diff --git a/src/containers/Chat/Chat.test.tsx b/src/containers/Chat/Chat.test.tsx index 4f244d537..dac0a8912 100644 --- a/src/containers/Chat/Chat.test.tsx +++ b/src/containers/Chat/Chat.test.tsx @@ -1,3 +1,4 @@ +import '../../matchMediaMock'; import { cleanup, render, waitFor } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; diff --git a/src/containers/Chat/ChatConversations/ConversationList/ConversationList.test.tsx b/src/containers/Chat/ChatConversations/ConversationList/ConversationList.test.tsx index 74615bf45..ae6d000c7 100644 --- a/src/containers/Chat/ChatConversations/ConversationList/ConversationList.test.tsx +++ b/src/containers/Chat/ChatConversations/ConversationList/ConversationList.test.tsx @@ -1,3 +1,4 @@ +import '../../../../matchMediaMock'; import { BrowserRouter as Router } from 'react-router-dom'; import { render, waitFor, screen, fireEvent } from '@testing-library/react'; import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'; diff --git a/src/containers/Chat/ChatInterface/ChatInterface.test.tsx b/src/containers/Chat/ChatInterface/ChatInterface.test.tsx index 5bbf98f95..bd23ae937 100644 --- a/src/containers/Chat/ChatInterface/ChatInterface.test.tsx +++ b/src/containers/Chat/ChatInterface/ChatInterface.test.tsx @@ -1,3 +1,4 @@ +import '../../../matchMediaMock'; import { MemoryRouter } from 'react-router-dom'; import { cleanup, render } from '@testing-library/react'; import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'; diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.module.css b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.module.css index 9037a8a9d..c79280e5b 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.module.css +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.module.css @@ -1,11 +1,7 @@ .ChatInput { - padding-top: 15px; - position: absolute; - bottom: 15px; background-color: #f9f7f4; - left: 0; - right: 0; margin: auto; + max-width: 100% !important; } .ChatInputElements { diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx index 12bb79c36..539ecf80e 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx @@ -1,3 +1,4 @@ +import '../../../../matchMediaMock'; import { MockedProvider } from '@apollo/client/testing'; import { render, waitFor, fireEvent } from '@testing-library/react'; import { vi } from 'vitest'; @@ -11,7 +12,7 @@ import { } from 'mocks/Attachment'; import { searchInteractive } from 'mocks/InteractiveMessage'; import '../VoiceRecorder/VoiceRecorder'; -import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { LexicalWrapper } from 'common/LexicalWrapper'; const mocks = [ searchInteractive, @@ -69,14 +70,9 @@ describe('', () => { const chatInput = ( - console.log(error), - }} - > + - + ); @@ -179,14 +175,9 @@ describe('', () => { propsWithBspStatusNone.contactBspStatus = 'NONE'; const { getByText } = render( - console.log(error), - }} - > + - + ); @@ -202,14 +193,9 @@ describe('', () => { propsWithBspStatusHSM.contactBspStatus = 'HSM'; const { getByText } = render( - console.log(error), - }} - > + - + ); expect(getByText('Templates')).toBeInTheDocument(); @@ -220,14 +206,9 @@ describe('', () => { propsWithBspStatusSession.contactBspStatus = 'SESSION'; const { getByText } = render( - console.log(error), - }} - > + - + ); expect(getByText('Speed sends')).toBeInTheDocument(); @@ -241,14 +222,9 @@ describe('', () => { const { getByText } = render( - console.log(error), - }} - > + - + ); expect(getByText('Templates')).toBeInTheDocument(); @@ -260,14 +236,9 @@ describe('', () => { propsWithMockSend.onSendMessage = sendMessageMock; const { getByText, getByTestId } = render( - console.log(error), - }} - > + - + ); diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index dee38deaf..a6ad344d9 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -31,6 +31,7 @@ import { $isRangeSelection, CLEAR_EDITOR_COMMAND, } from 'lexical'; +import { useResizeDetector } from 'react-resize-detector'; export interface ChatInputProps { onSendMessage( @@ -41,7 +42,6 @@ export interface ChatInputProps { variableParam: any, interactiveTemplateId?: any ): any; - handleHeightChange(newHeight: number): void; contactStatus?: string; contactBspStatus?: string; additionalStyle?: any; @@ -54,7 +54,6 @@ export const ChatInput = ({ contactBspStatus, contactStatus, additionalStyle, - handleHeightChange, isCollection, lastMessageTime, }: ChatInputProps) => { @@ -395,8 +394,17 @@ export const ChatInput = ({ dialog = ; } + const { ref } = useResizeDetector({ + refreshMode: 'debounce', + refreshRate: 1000, + onResize: (e) => { + console.log(e); + }, + }); + return ( @@ -433,7 +441,6 @@ export const ChatInput = ({ { }); fireEvent.scroll(messageContainer, { target: { scrollTop: 10 } }); - + screen.debug(undefined, Infinity); await waitFor(() => { fireEvent.click(getByTestId('jumpToLatest')); }); diff --git a/src/containers/Chat/ChatMessages/ChatMessages.tsx b/src/containers/Chat/ChatMessages/ChatMessages.tsx index e8c490874..d24839ccb 100644 --- a/src/containers/Chat/ChatMessages/ChatMessages.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessages.tsx @@ -28,7 +28,7 @@ import { import { getCachedConverations, updateConversationsCache } from '../../../services/ChatService'; import { addLogs, getDisplayName, isSimulator } from '../../../common/utils'; import { CollectionInformation } from '../../Collection/CollectionInformation/CollectionInformation'; -import { LexicalComposer } from '@lexical/react/LexicalComposer'; +import { LexicalWrapper } from 'common/LexicalWrapper'; export interface ChatMessagesProps { contactId?: number | string | null; @@ -54,7 +54,6 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe const [dialog, setDialogbox] = useState(); const [showDropdown, setShowDropdown] = useState(null); - const [reducedHeight, setReducedHeight] = useState(0); const [showLoadMore, setShowLoadMore] = useState(true); const [scrolledToMessage, setScrolledToMessage] = useState(false); const [showJumpToLatest, setShowJumpToLatest] = useState(false); @@ -87,7 +86,7 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe }); } }, 1000); - }, [setShowJumpToLatest, contactId, reducedHeight]); + }, [setShowJumpToLatest, contactId]); const scrollToLatestMessage = () => { const container: any = document.querySelector('.messageContainer'); @@ -593,7 +592,7 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe messageListContainer = ( @@ -626,10 +625,6 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe ); } - const handleHeightChange = (newHeight: number) => { - setReducedHeight(newHeight); - }; - const handleChatClearedAction = () => { const conversationInfoCopy = JSON.parse(JSON.stringify(conversationInfo)); conversationInfoCopy.messages = []; @@ -650,64 +645,6 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe ); } - let topChatBar; - let chatInputSection; - - if (contactId && conversationInfo.contact) { - const displayName = getDisplayName(conversationInfo); - topChatBar = ( - handleChatClearedAction()} - /> - ); - - chatInputSection = ( - console.log(error), - }} - > - - - ); - } else if (collectionId && conversationInfo.group) { - topChatBar = ( - - ); - - chatInputSection = ( - console.log(error), - }} - > - - - ); - } - const showLatestMessage = () => { setShowJumpToLatest(false); @@ -751,6 +688,55 @@ export const ChatMessages = ({ contactId, collectionId, startingHeight }: ChatMe
  • ); + let topChatBar; + let chatInputSection; + + if (contactId && conversationInfo.contact) { + const displayName = getDisplayName(conversationInfo); + topChatBar = ( + handleChatClearedAction()} + /> + ); + + chatInputSection = ( +
    + {conversationInfo.messages.length && showJumpToLatest ? jumpToLatest : null} + + + +
    + ); + } else if (collectionId && conversationInfo.group) { + topChatBar = ( + + ); + + chatInputSection = ( +
    + {conversationInfo.messages.length && showJumpToLatest ? jumpToLatest : null} + + + +
    + ); + } + return ( {messageListContainer} - {conversationInfo.messages.length && showJumpToLatest ? jumpToLatest : null} {chatInputSection} ); diff --git a/src/containers/InteractiveMessage/InteractiveMessage.test.tsx b/src/containers/InteractiveMessage/InteractiveMessage.test.tsx index d1c7c3a5b..7594603e4 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.test.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.test.tsx @@ -1,4 +1,4 @@ -import '../../matchMediMock'; +import '../../matchMediaMock'; import { render, screen, waitFor, fireEvent } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import axios from 'axios'; diff --git a/src/containers/InteractiveMessage/InteractiveMessage.tsx b/src/containers/InteractiveMessage/InteractiveMessage.tsx index 312925280..bc4e7fabc 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.tsx @@ -81,6 +81,11 @@ export const InteractiveMessage = () => { const { t } = useTranslation(); const params = useParams(); + let isEditing = false; + if (params.id) { + isEditing = true; + } + const isLocationRequestType = templateType === LOCATION_REQUEST; const { data: tag } = useQuery(GET_TAGS, { @@ -528,6 +533,7 @@ export const InteractiveMessage = () => { inputProp: { suggestions: contactVariables, }, + isEditing: isEditing, }, { skip: templateType !== QUICK_REPLY, diff --git a/src/containers/Template/Form/HSM/HSM.test.tsx b/src/containers/Template/Form/HSM/HSM.test.tsx index 4a184be9f..7d5579560 100644 --- a/src/containers/Template/Form/HSM/HSM.test.tsx +++ b/src/containers/Template/Form/HSM/HSM.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediMock'; +import '../../../../matchMediaMock'; import { render, waitFor, within, fireEvent } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import userEvent from '@testing-library/user-event'; diff --git a/src/containers/Template/Form/HSM/HSM.tsx b/src/containers/Template/Form/HSM/HSM.tsx index b7c383aeb..f25d3c0c4 100644 --- a/src/containers/Template/Form/HSM/HSM.tsx +++ b/src/containers/Template/Form/HSM/HSM.tsx @@ -108,6 +108,7 @@ export const HSM = () => { getEditorValue: (value: any) => { setExample(value); }, + isEditing: disabled, }, { component: AutoComplete, diff --git a/src/containers/Template/Form/SpeedSend/SpeedSend.test.tsx b/src/containers/Template/Form/SpeedSend/SpeedSend.test.tsx index 40ef85797..2faf7e004 100644 --- a/src/containers/Template/Form/SpeedSend/SpeedSend.test.tsx +++ b/src/containers/Template/Form/SpeedSend/SpeedSend.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediMock'; +import '../../../../matchMediaMock'; import { render, within, fireEvent, cleanup, waitFor } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; import { MockedProvider } from '@apollo/client/testing'; @@ -22,19 +22,6 @@ const mockIntersectionObserver = class { (window as any).IntersectionObserver = mockIntersectionObserver; -Object.defineProperty(window, 'matchMedia', { - writable: true, - value: (query: any) => { - return { - matches: false, - media: query, - onchange: null, - addListener: vi.fn(), - removeListener: vi.fn(), - }; - }, -}); - describe('SpeedSend', () => { test('cancel button should redirect to SpeedSendlist page', async () => { const { container, getByText } = render( diff --git a/src/containers/Template/Form/Template.test.tsx b/src/containers/Template/Form/Template.test.tsx index 8c4071f9c..92df577e0 100644 --- a/src/containers/Template/Form/Template.test.tsx +++ b/src/containers/Template/Form/Template.test.tsx @@ -1,4 +1,4 @@ -import '../../../matchMediMock' +import '../../../matchMediaMock'; import { render, waitFor, cleanup, fireEvent } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import { BrowserRouter } from 'react-router-dom'; diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index ee97d8583..d81ad191c 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -685,6 +685,7 @@ const Template = ({ getEditorValue: (value: any) => { setBody(value); }, + isEditing: isEditing, }, ]; diff --git a/src/matchMediMock.ts b/src/matchMediaMock.ts similarity index 100% rename from src/matchMediMock.ts rename to src/matchMediaMock.ts diff --git a/src/routes/AuthenticatedRoute/AuthenticatedRoute.test.tsx b/src/routes/AuthenticatedRoute/AuthenticatedRoute.test.tsx index 6a6aeda99..387e5b9ae 100644 --- a/src/routes/AuthenticatedRoute/AuthenticatedRoute.test.tsx +++ b/src/routes/AuthenticatedRoute/AuthenticatedRoute.test.tsx @@ -1,3 +1,4 @@ +import '../../matchMediaMock'; import { Suspense } from 'react'; import { render, waitFor } from '@testing-library/react'; import { BrowserRouter } from 'react-router-dom'; diff --git a/vite.config.ts.timestamp-1708584423070-641d506fb9214.mjs b/vite.config.ts.timestamp-1708584423070-641d506fb9214.mjs new file mode 100644 index 000000000..925ac7d54 --- /dev/null +++ b/vite.config.ts.timestamp-1708584423070-641d506fb9214.mjs @@ -0,0 +1,115 @@ +var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a, b) => (typeof require !== "undefined" ? require : a)[b] +}) : x)(function(x) { + if (typeof require !== "undefined") + return require.apply(this, arguments); + throw Error('Dynamic require of "' + x + '" is not supported'); +}); + +// vite.config.ts +import { defineConfig } from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/vite/dist/node/index.js"; +import react from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/@vitejs/plugin-react/dist/index.mjs"; +import viteTsconfigPaths from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/vite-tsconfig-paths/dist/index.mjs"; +import checker from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/vite-plugin-checker/dist/esm/main.js"; +import svgrPlugin from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/vite-plugin-svgr/dist/index.js"; +import fs from "fs"; +import nodePolyfills from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/rollup-plugin-polyfill-node/dist/index.js"; +var vite_config_default = ({ command, mode }) => { + if (mode === "test" && command === "serve") { + return defineConfig({ + // dev specific config + plugins: [react(), viteTsconfigPaths(), svgrPlugin()], + optimizeDeps: { + esbuildOptions: { + // Node.js global to browser globalThis + define: { + global: "globalThis" + } + } + }, + resolve: { alias: { util: "util/" } }, + test: { + globals: true, + environment: "jsdom", + setupFiles: "./src/setupTests.ts", + coverage: { + reporter: ["text", "html", "lcov"], + // choosing istanbul for now because of this https://github.com/vitest-dev/vitest/issues/1252 + provider: "istanbul", + // or 'c8' + exclude: ["node_modules/", "**/*.test.tsx"] + }, + css: true + } + }); + } + if (command === "serve") { + return defineConfig({ + // dev specific config + plugins: [react(), viteTsconfigPaths(), svgrPlugin(), checker({ typescript: true })], + optimizeDeps: { + esbuildOptions: { + // Node.js global to browser globalThis + define: { + global: "globalThis" + } + } + }, + server: { + open: true, + port: 3e3, + https: { + key: fs.readFileSync("../glific/priv/cert/glific.test+1-key.pem"), + cert: fs.readFileSync("../glific/priv/cert/glific.test+1.pem") + }, + headers: { + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "X-Frame-Options": "deny", + "Content-Security-Policy": "default-src * data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:; script-src-elem 'self' 'unsafe-inline' https://www.google.com https://www.gstatic.com; frame-src 'self' https://www.google.com https://www.gstatic.com data:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' data: https://fonts.gstatic.com; connect-src *;", + "Strict-Transport-Security": "max-age=63072000; includeSubdomains; preload" + } + }, + resolve: { alias: { util: "util/", stream: "stream-browserify" } } + // stream polyfill is needed by logflare + }); + } + return defineConfig({ + optimizeDeps: { + esbuildOptions: { + // Node.js global to browser globalThis + define: { + global: "globalThis" + } + } + }, + // build specific config + plugins: [react(), viteTsconfigPaths(), svgrPlugin()], + build: { + // this is needed because of this https://github.com/vitejs/vite/issues/2139#issuecomment-1405624744 + commonjsOptions: { + defaultIsModuleExports(id) { + try { + const module = __require(id); + if (module?.default) { + return false; + } + return "auto"; + } catch (error) { + return "auto"; + } + }, + transformMixedEsModules: true + }, + outDir: "build", + rollupOptions: { + plugins: [nodePolyfills("buffer", "process")] + } + }, + resolve: { alias: { util: "util/", stream: "stream-browserify" } } + }); +}; +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvVXNlcnMvYWthbnNoYS9EZXNrdG9wL2dsaWZpYzMvZ2xpZmljLWZyb250ZW5kXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvVXNlcnMvYWthbnNoYS9EZXNrdG9wL2dsaWZpYzMvZ2xpZmljLWZyb250ZW5kL3ZpdGUuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9ha2Fuc2hhL0Rlc2t0b3AvZ2xpZmljMy9nbGlmaWMtZnJvbnRlbmQvdml0ZS5jb25maWcudHNcIjsvLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGVzdFwiIC8+XG4vLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGUtcGx1Z2luLXN2Z3IvY2xpZW50XCIgLz5cbmltcG9ydCB7IGRlZmluZUNvbmZpZywgQ29uZmlnRW52LCBVc2VyQ29uZmlnRXhwb3J0IH0gZnJvbSAndml0ZSc7XG5pbXBvcnQgcmVhY3QgZnJvbSAnQHZpdGVqcy9wbHVnaW4tcmVhY3QnO1xuLy8gaW1wb3J0IGVzbGludCBmcm9tICd2aXRlLXBsdWdpbi1lc2xpbnQnO1xuaW1wb3J0IHZpdGVUc2NvbmZpZ1BhdGhzIGZyb20gJ3ZpdGUtdHNjb25maWctcGF0aHMnO1xuaW1wb3J0IGNoZWNrZXIgZnJvbSAndml0ZS1wbHVnaW4tY2hlY2tlcic7XG5pbXBvcnQgc3ZnclBsdWdpbiBmcm9tICd2aXRlLXBsdWdpbi1zdmdyJztcbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgbm9kZVBvbHlmaWxscyBmcm9tICdyb2xsdXAtcGx1Z2luLXBvbHlmaWxsLW5vZGUnO1xuXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xuZXhwb3J0IGRlZmF1bHQgKHsgY29tbWFuZCwgbW9kZSB9OiBDb25maWdFbnYpOiBVc2VyQ29uZmlnRXhwb3J0ID0+IHtcbiAgaWYgKG1vZGUgPT09ICd0ZXN0JyAmJiBjb21tYW5kID09PSAnc2VydmUnKSB7XG4gICAgcmV0dXJuIGRlZmluZUNvbmZpZyh7XG4gICAgICAvLyBkZXYgc3BlY2lmaWMgY29uZmlnXG4gICAgICBwbHVnaW5zOiBbcmVhY3QoKSwgdml0ZVRzY29uZmlnUGF0aHMoKSwgc3ZnclBsdWdpbigpXSxcblxuICAgICAgb3B0aW1pemVEZXBzOiB7XG4gICAgICAgIGVzYnVpbGRPcHRpb25zOiB7XG4gICAgICAgICAgLy8gTm9kZS5qcyBnbG9iYWwgdG8gYnJvd3NlciBnbG9iYWxUaGlzXG4gICAgICAgICAgZGVmaW5lOiB7XG4gICAgICAgICAgICBnbG9iYWw6ICdnbG9iYWxUaGlzJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcblxuICAgICAgcmVzb2x2ZTogeyBhbGlhczogeyB1dGlsOiAndXRpbC8nIH0gfSxcbiAgICAgIHRlc3Q6IHtcbiAgICAgICAgZ2xvYmFsczogdHJ1ZSxcbiAgICAgICAgZW52aXJvbm1lbnQ6ICdqc2RvbScsXG4gICAgICAgIHNldHVwRmlsZXM6ICcuL3NyYy9zZXR1cFRlc3RzLnRzJyxcbiAgICAgICAgY292ZXJhZ2U6IHtcbiAgICAgICAgICByZXBvcnRlcjogWyd0ZXh0JywgJ2h0bWwnLCAnbGNvdiddLFxuICAgICAgICAgIC8vIGNob29zaW5nIGlzdGFuYnVsIGZvciBub3cgYmVjYXVzZSBvZiB0aGlzIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRlc3QtZGV2L3ZpdGVzdC9pc3N1ZXMvMTI1MlxuICAgICAgICAgIHByb3ZpZGVyOiAnaXN0YW5idWwnLCAvLyBvciAnYzgnXG4gICAgICAgICAgZXhjbHVkZTogWydub2RlX21vZHVsZXMvJywgJyoqLyoudGVzdC50c3gnXSxcbiAgICAgICAgfSxcbiAgICAgICAgY3NzOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuICBpZiAoY29tbWFuZCA9PT0gJ3NlcnZlJykge1xuICAgIHJldHVybiBkZWZpbmVDb25maWcoe1xuICAgICAgLy8gZGV2IHNwZWNpZmljIGNvbmZpZ1xuICAgICAgcGx1Z2luczogW3JlYWN0KCksIHZpdGVUc2NvbmZpZ1BhdGhzKCksIHN2Z3JQbHVnaW4oKSwgY2hlY2tlcih7IHR5cGVzY3JpcHQ6IHRydWUgfSldLFxuICAgICAgb3B0aW1pemVEZXBzOiB7XG4gICAgICAgIGVzYnVpbGRPcHRpb25zOiB7XG4gICAgICAgICAgLy8gTm9kZS5qcyBnbG9iYWwgdG8gYnJvd3NlciBnbG9iYWxUaGlzXG4gICAgICAgICAgZGVmaW5lOiB7XG4gICAgICAgICAgICBnbG9iYWw6ICdnbG9iYWxUaGlzJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHNlcnZlcjoge1xuICAgICAgICBvcGVuOiB0cnVlLFxuICAgICAgICBwb3J0OiAzMDAwLFxuICAgICAgICBodHRwczoge1xuICAgICAgICAgIGtleTogZnMucmVhZEZpbGVTeW5jKCcuLi9nbGlmaWMvcHJpdi9jZXJ0L2dsaWZpYy50ZXN0KzEta2V5LnBlbScpLFxuICAgICAgICAgIGNlcnQ6IGZzLnJlYWRGaWxlU3luYygnLi4vZ2xpZmljL3ByaXYvY2VydC9nbGlmaWMudGVzdCsxLnBlbScpLFxuICAgICAgICB9LFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1gtQ29udGVudC1UeXBlLU9wdGlvbnMnOiAnbm9zbmlmZicsXG4gICAgICAgICAgJ1gtWFNTLVByb3RlY3Rpb24nOiAnMTsgbW9kZT1ibG9jaycsXG4gICAgICAgICAgJ1gtRnJhbWUtT3B0aW9ucyc6ICdkZW55JyxcbiAgICAgICAgICAnQ29udGVudC1TZWN1cml0eS1Qb2xpY3knOlxuICAgICAgICAgICAgXCJkZWZhdWx0LXNyYyAqIGRhdGE6OyBzY3JpcHQtc3JjICdzZWxmJyAndW5zYWZlLWlubGluZScgJ3Vuc2FmZS1ldmFsJyBibG9iOjsgc2NyaXB0LXNyYy1lbGVtICdzZWxmJyAndW5zYWZlLWlubGluZScgaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbSBodHRwczovL3d3dy5nc3RhdGljLmNvbTsgZnJhbWUtc3JjICdzZWxmJyBodHRwczovL3d3dy5nb29nbGUuY29tIGh0dHBzOi8vd3d3LmdzdGF0aWMuY29tIGRhdGE6OyBzdHlsZS1zcmMgJ3NlbGYnICd1bnNhZmUtaW5saW5lJyBodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tOyBmb250LXNyYyAnc2VsZicgZGF0YTogaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbTsgY29ubmVjdC1zcmMgKjtcIixcbiAgICAgICAgICAnU3RyaWN0LVRyYW5zcG9ydC1TZWN1cml0eSc6ICdtYXgtYWdlPTYzMDcyMDAwOyBpbmNsdWRlU3ViZG9tYWluczsgcHJlbG9hZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcmVzb2x2ZTogeyBhbGlhczogeyB1dGlsOiAndXRpbC8nLCBzdHJlYW06ICdzdHJlYW0tYnJvd3NlcmlmeScgfSB9LCAvLyBzdHJlYW0gcG9seWZpbGwgaXMgbmVlZGVkIGJ5IGxvZ2ZsYXJlXG4gICAgfSk7XG4gIH1cbiAgLy8gY29tbWFuZCA9PT0gJ2J1aWxkJ1xuICByZXR1cm4gZGVmaW5lQ29uZmlnKHtcbiAgICBvcHRpbWl6ZURlcHM6IHtcbiAgICAgIGVzYnVpbGRPcHRpb25zOiB7XG4gICAgICAgIC8vIE5vZGUuanMgZ2xvYmFsIHRvIGJyb3dzZXIgZ2xvYmFsVGhpc1xuICAgICAgICBkZWZpbmU6IHtcbiAgICAgICAgICBnbG9iYWw6ICdnbG9iYWxUaGlzJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICAvLyBidWlsZCBzcGVjaWZpYyBjb25maWdcbiAgICBwbHVnaW5zOiBbcmVhY3QoKSwgdml0ZVRzY29uZmlnUGF0aHMoKSwgc3ZnclBsdWdpbigpXSxcbiAgICBidWlsZDoge1xuICAgICAgLy8gdGhpcyBpcyBuZWVkZWQgYmVjYXVzZSBvZiB0aGlzIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRlanMvdml0ZS9pc3N1ZXMvMjEzOSNpc3N1ZWNvbW1lbnQtMTQwNTYyNDc0NFxuICAgICAgY29tbW9uanNPcHRpb25zOiB7XG4gICAgICAgIGRlZmF1bHRJc01vZHVsZUV4cG9ydHMoaWQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgbW9kdWxlID0gcmVxdWlyZShpZCk7XG4gICAgICAgICAgICBpZiAobW9kdWxlPy5kZWZhdWx0KSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAnYXV0byc7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiAnYXV0byc7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB0cmFuc2Zvcm1NaXhlZEVzTW9kdWxlczogdHJ1ZSxcbiAgICAgIH0sXG4gICAgICBvdXREaXI6ICdidWlsZCcsXG4gICAgICByb2xsdXBPcHRpb25zOiB7XG4gICAgICAgIHBsdWdpbnM6IFtub2RlUG9seWZpbGxzKCdidWZmZXInLCAncHJvY2VzcycpXSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICByZXNvbHZlOiB7IGFsaWFzOiB7IHV0aWw6ICd1dGlsLycsIHN0cmVhbTogJ3N0cmVhbS1icm93c2VyaWZ5JyB9IH0sXG4gIH0pO1xufTtcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7OztBQUVBLFNBQVMsb0JBQWlEO0FBQzFELE9BQU8sV0FBVztBQUVsQixPQUFPLHVCQUF1QjtBQUM5QixPQUFPLGFBQWE7QUFDcEIsT0FBTyxnQkFBZ0I7QUFDdkIsT0FBTyxRQUFRO0FBQ2YsT0FBTyxtQkFBbUI7QUFHMUIsSUFBTyxzQkFBUSxDQUFDLEVBQUUsU0FBUyxLQUFLLE1BQW1DO0FBQ2pFLE1BQUksU0FBUyxVQUFVLFlBQVksU0FBUztBQUMxQyxXQUFPLGFBQWE7QUFBQTtBQUFBLE1BRWxCLFNBQVMsQ0FBQyxNQUFNLEdBQUcsa0JBQWtCLEdBQUcsV0FBVyxDQUFDO0FBQUEsTUFFcEQsY0FBYztBQUFBLFFBQ1osZ0JBQWdCO0FBQUE7QUFBQSxVQUVkLFFBQVE7QUFBQSxZQUNOLFFBQVE7QUFBQSxVQUNWO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFBQSxNQUVBLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxRQUFRLEVBQUU7QUFBQSxNQUNwQyxNQUFNO0FBQUEsUUFDSixTQUFTO0FBQUEsUUFDVCxhQUFhO0FBQUEsUUFDYixZQUFZO0FBQUEsUUFDWixVQUFVO0FBQUEsVUFDUixVQUFVLENBQUMsUUFBUSxRQUFRLE1BQU07QUFBQTtBQUFBLFVBRWpDLFVBQVU7QUFBQTtBQUFBLFVBQ1YsU0FBUyxDQUFDLGlCQUFpQixlQUFlO0FBQUEsUUFDNUM7QUFBQSxRQUNBLEtBQUs7QUFBQSxNQUNQO0FBQUEsSUFDRixDQUFDO0FBQUEsRUFDSDtBQUNBLE1BQUksWUFBWSxTQUFTO0FBQ3ZCLFdBQU8sYUFBYTtBQUFBO0FBQUEsTUFFbEIsU0FBUyxDQUFDLE1BQU0sR0FBRyxrQkFBa0IsR0FBRyxXQUFXLEdBQUcsUUFBUSxFQUFFLFlBQVksS0FBSyxDQUFDLENBQUM7QUFBQSxNQUNuRixjQUFjO0FBQUEsUUFDWixnQkFBZ0I7QUFBQTtBQUFBLFVBRWQsUUFBUTtBQUFBLFlBQ04sUUFBUTtBQUFBLFVBQ1Y7QUFBQSxRQUNGO0FBQUEsTUFDRjtBQUFBLE1BQ0EsUUFBUTtBQUFBLFFBQ04sTUFBTTtBQUFBLFFBQ04sTUFBTTtBQUFBLFFBQ04sT0FBTztBQUFBLFVBQ0wsS0FBSyxHQUFHLGFBQWEsMkNBQTJDO0FBQUEsVUFDaEUsTUFBTSxHQUFHLGFBQWEsdUNBQXVDO0FBQUEsUUFDL0Q7QUFBQSxRQUNBLFNBQVM7QUFBQSxVQUNQLDBCQUEwQjtBQUFBLFVBQzFCLG9CQUFvQjtBQUFBLFVBQ3BCLG1CQUFtQjtBQUFBLFVBQ25CLDJCQUNFO0FBQUEsVUFDRiw2QkFBNkI7QUFBQSxRQUMvQjtBQUFBLE1BQ0Y7QUFBQSxNQUNBLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxTQUFTLFFBQVEsb0JBQW9CLEVBQUU7QUFBQTtBQUFBLElBQ25FLENBQUM7QUFBQSxFQUNIO0FBRUEsU0FBTyxhQUFhO0FBQUEsSUFDbEIsY0FBYztBQUFBLE1BQ1osZ0JBQWdCO0FBQUE7QUFBQSxRQUVkLFFBQVE7QUFBQSxVQUNOLFFBQVE7QUFBQSxRQUNWO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQTtBQUFBLElBRUEsU0FBUyxDQUFDLE1BQU0sR0FBRyxrQkFBa0IsR0FBRyxXQUFXLENBQUM7QUFBQSxJQUNwRCxPQUFPO0FBQUE7QUFBQSxNQUVMLGlCQUFpQjtBQUFBLFFBQ2YsdUJBQXVCLElBQUk7QUFDekIsY0FBSTtBQUNGLGtCQUFNLFNBQVMsVUFBUSxFQUFFO0FBQ3pCLGdCQUFJLFFBQVEsU0FBUztBQUNuQixxQkFBTztBQUFBLFlBQ1Q7QUFDQSxtQkFBTztBQUFBLFVBQ1QsU0FBUyxPQUFPO0FBQ2QsbUJBQU87QUFBQSxVQUNUO0FBQUEsUUFDRjtBQUFBLFFBQ0EseUJBQXlCO0FBQUEsTUFDM0I7QUFBQSxNQUNBLFFBQVE7QUFBQSxNQUNSLGVBQWU7QUFBQSxRQUNiLFNBQVMsQ0FBQyxjQUFjLFVBQVUsU0FBUyxDQUFDO0FBQUEsTUFDOUM7QUFBQSxJQUNGO0FBQUEsSUFDQSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sU0FBUyxRQUFRLG9CQUFvQixFQUFFO0FBQUEsRUFDbkUsQ0FBQztBQUNIOyIsCiAgIm5hbWVzIjogW10KfQo= From afb601f73cdf27c2a48e561387c2a33a0ba6217f Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Thu, 22 Feb 2024 14:39:51 +0530 Subject: [PATCH 28/36] changes cypress branch --- .github/workflows/cypress-testing.yml | 2 +- .../UI/Form/EmojiInput/Editor.test.tsx | 30 +------------------ src/components/UI/Form/EmojiInput/Editor.tsx | 1 - .../UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 2 +- .../InteractiveMessage/InteractiveMessage.tsx | 2 +- 5 files changed, 4 insertions(+), 33 deletions(-) diff --git a/.github/workflows/cypress-testing.yml b/.github/workflows/cypress-testing.yml index aaf344530..1429d043c 100644 --- a/.github/workflows/cypress-testing.yml +++ b/.github/workflows/cypress-testing.yml @@ -4,7 +4,7 @@ on: push: branches: [master] pull_request: - branches: [master] + branches: [master, 'lexical-editor'] jobs: glific: diff --git a/src/components/UI/Form/EmojiInput/Editor.test.tsx b/src/components/UI/Form/EmojiInput/Editor.test.tsx index 1b26a8e23..a32d5208e 100644 --- a/src/components/UI/Form/EmojiInput/Editor.test.tsx +++ b/src/components/UI/Form/EmojiInput/Editor.test.tsx @@ -1,11 +1,8 @@ import '../../../../matchMediaMock'; -import { act, fireEvent, render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; +import { render } from '@testing-library/react'; import { Editor } from './Editor'; import { LexicalWrapper } from 'common/LexicalWrapper'; -const setFieldValueMock = vi.fn(); - const mockIntersectionObserver = class { constructor() {} observe() {} @@ -30,30 +27,5 @@ const wrapper = ( it('should render lexical editor', () => { const { getByTestId } = render(wrapper); - expect(getByTestId('editor-body')).toBeInTheDocument(); }); - -it('shoul open contact variables dropdown', async () => { - const { getByTestId } = render(wrapper); - const editor = getByTestId('editor-body'); - - await userEvent.click(editor); - await userEvent.tab(); - userEvent.keyboard('ddd'); - // await fireEvent.input(editor, { data: 'this text is bold' }); - screen.debug(); -}); - -// it('should render make text bold', async () => { -// const { getByTestId } = render(wrapper); -// const editor = getByTestId('editor-body'); -// await userEvent.click(editor); -// // await userEvent.keyboard('this text is bold'); -// await userEvent.tab(); -// act(async () => { -// await fireEvent.input(editor, { data: 'this text is bold' }); -// }); -// screen.debug(); -// expect(getByTestId('editor-body')).toBeInTheDocument(); -// }); diff --git a/src/components/UI/Form/EmojiInput/Editor.tsx b/src/components/UI/Form/EmojiInput/Editor.tsx index d9366f2a3..c5ab1912c 100644 --- a/src/components/UI/Form/EmojiInput/Editor.tsx +++ b/src/components/UI/Form/EmojiInput/Editor.tsx @@ -43,7 +43,6 @@ export const Editor = ({ disabled = false, isEditing = false, ...props }: Editor const suggestions = { '@': mentions.map((mention: string) => mention?.split('@')[1]), }; - const params = useParams(); const [editor] = useLexicalComposerContext(); useEffect(() => { diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index c42dc3f2b..f67acf9a4 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect } from 'react'; +import { useEffect } from 'react'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; diff --git a/src/containers/InteractiveMessage/InteractiveMessage.tsx b/src/containers/InteractiveMessage/InteractiveMessage.tsx index bc4e7fabc..a2bb6d371 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.tsx @@ -82,7 +82,7 @@ export const InteractiveMessage = () => { const params = useParams(); let isEditing = false; - if (params.id) { + if (params?.id) { isEditing = true; } From 66e429ecc9a48ae0fcac9d1d03516d3a78237474 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Thu, 22 Feb 2024 14:41:41 +0530 Subject: [PATCH 29/36] resolved minor issue --- src/components/UI/Form/EmojiInput/Editor.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/UI/Form/EmojiInput/Editor.tsx b/src/components/UI/Form/EmojiInput/Editor.tsx index c5ab1912c..89eb26e69 100644 --- a/src/components/UI/Form/EmojiInput/Editor.tsx +++ b/src/components/UI/Form/EmojiInput/Editor.tsx @@ -21,7 +21,6 @@ import { BeautifulMentionsMenuProps, BeautifulMentionsMenuItemProps, } from 'lexical-beautiful-mentions'; -import { useParams } from 'react-router'; import { handleFormatterEvents, handleFormatting } from 'common/RichEditor'; export interface EditorProps { From 20c595bc319bc7ec1bdf78d02e400210ac8cd8c8 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Thu, 22 Feb 2024 14:45:39 +0530 Subject: [PATCH 30/36] resolved minor issue --- src/components/UI/Form/EmojiInput/Editor.tsx | 8 +------- src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx | 9 --------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/components/UI/Form/EmojiInput/Editor.tsx b/src/components/UI/Form/EmojiInput/Editor.tsx index 89eb26e69..e7c46ef47 100644 --- a/src/components/UI/Form/EmojiInput/Editor.tsx +++ b/src/components/UI/Form/EmojiInput/Editor.tsx @@ -13,7 +13,6 @@ import { import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; -import { useResizeDetector } from 'react-resize-detector'; import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; import { FormHelperText } from '@mui/material'; import { @@ -56,11 +55,6 @@ export const Editor = ({ disabled = false, isEditing = false, ...props }: Editor } }, [field.value]); - const { ref } = useResizeDetector({ - refreshMode: 'debounce', - refreshRate: 1000, - }); - const Placeholder = () => { return

    {placeholder}

    ; }; @@ -103,7 +97,7 @@ export const Editor = ({ disabled = false, isEditing = false, ...props }: Editor return (
    -
    +
    } contentEditable={ diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index a6ad344d9..c330497b5 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -31,7 +31,6 @@ import { $isRangeSelection, CLEAR_EDITOR_COMMAND, } from 'lexical'; -import { useResizeDetector } from 'react-resize-detector'; export interface ChatInputProps { onSendMessage( @@ -394,14 +393,6 @@ export const ChatInput = ({ dialog = ; } - const { ref } = useResizeDetector({ - refreshMode: 'debounce', - refreshRate: 1000, - onResize: (e) => { - console.log(e); - }, - }); - return ( Date: Thu, 22 Feb 2024 14:49:40 +0530 Subject: [PATCH 31/36] resolved minor issue --- src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx | 1 - src/containers/Chat/ChatMessages/ChatMessages.test.tsx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx index c330497b5..27307df81 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.tsx @@ -395,7 +395,6 @@ export const ChatInput = ({ return ( diff --git a/src/containers/Chat/ChatMessages/ChatMessages.test.tsx b/src/containers/Chat/ChatMessages/ChatMessages.test.tsx index b08b23231..4c63d8490 100644 --- a/src/containers/Chat/ChatMessages/ChatMessages.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessages.test.tsx @@ -329,7 +329,7 @@ test('Collection: click on Jump to latest', async () => { }); fireEvent.scroll(messageContainer, { target: { scrollTop: 10 } }); - screen.debug(undefined, Infinity); + await waitFor(() => { fireEvent.click(getByTestId('jumpToLatest')); }); From b6ae3728f92d83797cefc1619436c0694a1a0487 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Thu, 22 Feb 2024 16:48:32 +0530 Subject: [PATCH 32/36] resolved minor issue --- .github/workflows/cypress-testing.yml | 5 ++++- src/common/RichEditor.tsx | 2 -- src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cypress-testing.yml b/.github/workflows/cypress-testing.yml index 1429d043c..a0de45161 100644 --- a/.github/workflows/cypress-testing.yml +++ b/.github/workflows/cypress-testing.yml @@ -4,7 +4,7 @@ on: push: branches: [master] pull_request: - branches: [master, 'lexical-editor'] + branches: [master, 'migration-from-draft-js'] jobs: glific: @@ -95,6 +95,9 @@ jobs: echo clone cypress repo git clone https://github.com/glific/cypress-testing.git echo done. go to dir. + cd cypress-testing + git checkout lexical-editor + cd .. cp -r cypress-testing/cypress cypress yarn add cypress echo Create cypress.config.ts from example diff --git a/src/common/RichEditor.tsx b/src/common/RichEditor.tsx index 7e2a06a86..c439cf26e 100644 --- a/src/common/RichEditor.tsx +++ b/src/common/RichEditor.tsx @@ -7,8 +7,6 @@ import { UrlMatcher } from 'interweave-autolink'; const regexForLink = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)/gi; -export const getTextContent = (editorState: any) => editorState?.getRootElement()?.textContent; - export const handleFormatterEvents = (event: KeyboardEvent) => { if ((event.ctrlKey || event.metaKey) && event.code === 'KeyB') { return 'bold'; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx index f67acf9a4..90fb848be 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.tsx @@ -16,7 +16,7 @@ import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'; import { useResizeDetector } from 'react-resize-detector'; import styles from './WhatsAppEditor.module.css'; -import { getTextContent, handleFormatterEvents, handleFormatting } from 'common/RichEditor'; +import { handleFormatterEvents, handleFormatting } from 'common/RichEditor'; interface WhatsAppEditorProps { sendMessage(message: any): void; @@ -57,7 +57,8 @@ export const WhatsAppEditor = ({ let formatter = ''; if (event.code === 'Enter' && !event.shiftKey) { event.preventDefault(); - let textMessage = getTextContent(editor); + const root = $getRoot(); + let textMessage = root.getTextContent(); sendMessage(textMessage); return true; } else { From 627a626c873f3b6580225fd63f6f2c25e7171725 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Thu, 22 Feb 2024 16:59:54 +0530 Subject: [PATCH 33/36] Update cypress-testing.yml --- .github/workflows/cypress-testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress-testing.yml b/.github/workflows/cypress-testing.yml index a0de45161..4004b6b2b 100644 --- a/.github/workflows/cypress-testing.yml +++ b/.github/workflows/cypress-testing.yml @@ -4,7 +4,7 @@ on: push: branches: [master] pull_request: - branches: [master, 'migration-from-draft-js'] + branches: [master, migration-from-draft-js] jobs: glific: From 8931299ce7b2210b6c7fd4f8d3a38e3f7d016e39 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Thu, 22 Feb 2024 20:21:16 +0530 Subject: [PATCH 34/36] Delete vite.config.ts.timestamp-1708584423070-641d506fb9214.mjs --- ....timestamp-1708584423070-641d506fb9214.mjs | 115 ------------------ 1 file changed, 115 deletions(-) delete mode 100644 vite.config.ts.timestamp-1708584423070-641d506fb9214.mjs diff --git a/vite.config.ts.timestamp-1708584423070-641d506fb9214.mjs b/vite.config.ts.timestamp-1708584423070-641d506fb9214.mjs deleted file mode 100644 index 925ac7d54..000000000 --- a/vite.config.ts.timestamp-1708584423070-641d506fb9214.mjs +++ /dev/null @@ -1,115 +0,0 @@ -var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { - get: (a, b) => (typeof require !== "undefined" ? require : a)[b] -}) : x)(function(x) { - if (typeof require !== "undefined") - return require.apply(this, arguments); - throw Error('Dynamic require of "' + x + '" is not supported'); -}); - -// vite.config.ts -import { defineConfig } from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/vite/dist/node/index.js"; -import react from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/@vitejs/plugin-react/dist/index.mjs"; -import viteTsconfigPaths from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/vite-tsconfig-paths/dist/index.mjs"; -import checker from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/vite-plugin-checker/dist/esm/main.js"; -import svgrPlugin from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/vite-plugin-svgr/dist/index.js"; -import fs from "fs"; -import nodePolyfills from "file:///Users/akansha/Desktop/glific3/glific-frontend/node_modules/rollup-plugin-polyfill-node/dist/index.js"; -var vite_config_default = ({ command, mode }) => { - if (mode === "test" && command === "serve") { - return defineConfig({ - // dev specific config - plugins: [react(), viteTsconfigPaths(), svgrPlugin()], - optimizeDeps: { - esbuildOptions: { - // Node.js global to browser globalThis - define: { - global: "globalThis" - } - } - }, - resolve: { alias: { util: "util/" } }, - test: { - globals: true, - environment: "jsdom", - setupFiles: "./src/setupTests.ts", - coverage: { - reporter: ["text", "html", "lcov"], - // choosing istanbul for now because of this https://github.com/vitest-dev/vitest/issues/1252 - provider: "istanbul", - // or 'c8' - exclude: ["node_modules/", "**/*.test.tsx"] - }, - css: true - } - }); - } - if (command === "serve") { - return defineConfig({ - // dev specific config - plugins: [react(), viteTsconfigPaths(), svgrPlugin(), checker({ typescript: true })], - optimizeDeps: { - esbuildOptions: { - // Node.js global to browser globalThis - define: { - global: "globalThis" - } - } - }, - server: { - open: true, - port: 3e3, - https: { - key: fs.readFileSync("../glific/priv/cert/glific.test+1-key.pem"), - cert: fs.readFileSync("../glific/priv/cert/glific.test+1.pem") - }, - headers: { - "X-Content-Type-Options": "nosniff", - "X-XSS-Protection": "1; mode=block", - "X-Frame-Options": "deny", - "Content-Security-Policy": "default-src * data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:; script-src-elem 'self' 'unsafe-inline' https://www.google.com https://www.gstatic.com; frame-src 'self' https://www.google.com https://www.gstatic.com data:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' data: https://fonts.gstatic.com; connect-src *;", - "Strict-Transport-Security": "max-age=63072000; includeSubdomains; preload" - } - }, - resolve: { alias: { util: "util/", stream: "stream-browserify" } } - // stream polyfill is needed by logflare - }); - } - return defineConfig({ - optimizeDeps: { - esbuildOptions: { - // Node.js global to browser globalThis - define: { - global: "globalThis" - } - } - }, - // build specific config - plugins: [react(), viteTsconfigPaths(), svgrPlugin()], - build: { - // this is needed because of this https://github.com/vitejs/vite/issues/2139#issuecomment-1405624744 - commonjsOptions: { - defaultIsModuleExports(id) { - try { - const module = __require(id); - if (module?.default) { - return false; - } - return "auto"; - } catch (error) { - return "auto"; - } - }, - transformMixedEsModules: true - }, - outDir: "build", - rollupOptions: { - plugins: [nodePolyfills("buffer", "process")] - } - }, - resolve: { alias: { util: "util/", stream: "stream-browserify" } } - }); -}; -export { - vite_config_default as default -}; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvVXNlcnMvYWthbnNoYS9EZXNrdG9wL2dsaWZpYzMvZ2xpZmljLWZyb250ZW5kXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCIvVXNlcnMvYWthbnNoYS9EZXNrdG9wL2dsaWZpYzMvZ2xpZmljLWZyb250ZW5kL3ZpdGUuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9ha2Fuc2hhL0Rlc2t0b3AvZ2xpZmljMy9nbGlmaWMtZnJvbnRlbmQvdml0ZS5jb25maWcudHNcIjsvLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGVzdFwiIC8+XG4vLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGUtcGx1Z2luLXN2Z3IvY2xpZW50XCIgLz5cbmltcG9ydCB7IGRlZmluZUNvbmZpZywgQ29uZmlnRW52LCBVc2VyQ29uZmlnRXhwb3J0IH0gZnJvbSAndml0ZSc7XG5pbXBvcnQgcmVhY3QgZnJvbSAnQHZpdGVqcy9wbHVnaW4tcmVhY3QnO1xuLy8gaW1wb3J0IGVzbGludCBmcm9tICd2aXRlLXBsdWdpbi1lc2xpbnQnO1xuaW1wb3J0IHZpdGVUc2NvbmZpZ1BhdGhzIGZyb20gJ3ZpdGUtdHNjb25maWctcGF0aHMnO1xuaW1wb3J0IGNoZWNrZXIgZnJvbSAndml0ZS1wbHVnaW4tY2hlY2tlcic7XG5pbXBvcnQgc3ZnclBsdWdpbiBmcm9tICd2aXRlLXBsdWdpbi1zdmdyJztcbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgbm9kZVBvbHlmaWxscyBmcm9tICdyb2xsdXAtcGx1Z2luLXBvbHlmaWxsLW5vZGUnO1xuXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xuZXhwb3J0IGRlZmF1bHQgKHsgY29tbWFuZCwgbW9kZSB9OiBDb25maWdFbnYpOiBVc2VyQ29uZmlnRXhwb3J0ID0+IHtcbiAgaWYgKG1vZGUgPT09ICd0ZXN0JyAmJiBjb21tYW5kID09PSAnc2VydmUnKSB7XG4gICAgcmV0dXJuIGRlZmluZUNvbmZpZyh7XG4gICAgICAvLyBkZXYgc3BlY2lmaWMgY29uZmlnXG4gICAgICBwbHVnaW5zOiBbcmVhY3QoKSwgdml0ZVRzY29uZmlnUGF0aHMoKSwgc3ZnclBsdWdpbigpXSxcblxuICAgICAgb3B0aW1pemVEZXBzOiB7XG4gICAgICAgIGVzYnVpbGRPcHRpb25zOiB7XG4gICAgICAgICAgLy8gTm9kZS5qcyBnbG9iYWwgdG8gYnJvd3NlciBnbG9iYWxUaGlzXG4gICAgICAgICAgZGVmaW5lOiB7XG4gICAgICAgICAgICBnbG9iYWw6ICdnbG9iYWxUaGlzJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcblxuICAgICAgcmVzb2x2ZTogeyBhbGlhczogeyB1dGlsOiAndXRpbC8nIH0gfSxcbiAgICAgIHRlc3Q6IHtcbiAgICAgICAgZ2xvYmFsczogdHJ1ZSxcbiAgICAgICAgZW52aXJvbm1lbnQ6ICdqc2RvbScsXG4gICAgICAgIHNldHVwRmlsZXM6ICcuL3NyYy9zZXR1cFRlc3RzLnRzJyxcbiAgICAgICAgY292ZXJhZ2U6IHtcbiAgICAgICAgICByZXBvcnRlcjogWyd0ZXh0JywgJ2h0bWwnLCAnbGNvdiddLFxuICAgICAgICAgIC8vIGNob29zaW5nIGlzdGFuYnVsIGZvciBub3cgYmVjYXVzZSBvZiB0aGlzIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRlc3QtZGV2L3ZpdGVzdC9pc3N1ZXMvMTI1MlxuICAgICAgICAgIHByb3ZpZGVyOiAnaXN0YW5idWwnLCAvLyBvciAnYzgnXG4gICAgICAgICAgZXhjbHVkZTogWydub2RlX21vZHVsZXMvJywgJyoqLyoudGVzdC50c3gnXSxcbiAgICAgICAgfSxcbiAgICAgICAgY3NzOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuICBpZiAoY29tbWFuZCA9PT0gJ3NlcnZlJykge1xuICAgIHJldHVybiBkZWZpbmVDb25maWcoe1xuICAgICAgLy8gZGV2IHNwZWNpZmljIGNvbmZpZ1xuICAgICAgcGx1Z2luczogW3JlYWN0KCksIHZpdGVUc2NvbmZpZ1BhdGhzKCksIHN2Z3JQbHVnaW4oKSwgY2hlY2tlcih7IHR5cGVzY3JpcHQ6IHRydWUgfSldLFxuICAgICAgb3B0aW1pemVEZXBzOiB7XG4gICAgICAgIGVzYnVpbGRPcHRpb25zOiB7XG4gICAgICAgICAgLy8gTm9kZS5qcyBnbG9iYWwgdG8gYnJvd3NlciBnbG9iYWxUaGlzXG4gICAgICAgICAgZGVmaW5lOiB7XG4gICAgICAgICAgICBnbG9iYWw6ICdnbG9iYWxUaGlzJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHNlcnZlcjoge1xuICAgICAgICBvcGVuOiB0cnVlLFxuICAgICAgICBwb3J0OiAzMDAwLFxuICAgICAgICBodHRwczoge1xuICAgICAgICAgIGtleTogZnMucmVhZEZpbGVTeW5jKCcuLi9nbGlmaWMvcHJpdi9jZXJ0L2dsaWZpYy50ZXN0KzEta2V5LnBlbScpLFxuICAgICAgICAgIGNlcnQ6IGZzLnJlYWRGaWxlU3luYygnLi4vZ2xpZmljL3ByaXYvY2VydC9nbGlmaWMudGVzdCsxLnBlbScpLFxuICAgICAgICB9LFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1gtQ29udGVudC1UeXBlLU9wdGlvbnMnOiAnbm9zbmlmZicsXG4gICAgICAgICAgJ1gtWFNTLVByb3RlY3Rpb24nOiAnMTsgbW9kZT1ibG9jaycsXG4gICAgICAgICAgJ1gtRnJhbWUtT3B0aW9ucyc6ICdkZW55JyxcbiAgICAgICAgICAnQ29udGVudC1TZWN1cml0eS1Qb2xpY3knOlxuICAgICAgICAgICAgXCJkZWZhdWx0LXNyYyAqIGRhdGE6OyBzY3JpcHQtc3JjICdzZWxmJyAndW5zYWZlLWlubGluZScgJ3Vuc2FmZS1ldmFsJyBibG9iOjsgc2NyaXB0LXNyYy1lbGVtICdzZWxmJyAndW5zYWZlLWlubGluZScgaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbSBodHRwczovL3d3dy5nc3RhdGljLmNvbTsgZnJhbWUtc3JjICdzZWxmJyBodHRwczovL3d3dy5nb29nbGUuY29tIGh0dHBzOi8vd3d3LmdzdGF0aWMuY29tIGRhdGE6OyBzdHlsZS1zcmMgJ3NlbGYnICd1bnNhZmUtaW5saW5lJyBodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tOyBmb250LXNyYyAnc2VsZicgZGF0YTogaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbTsgY29ubmVjdC1zcmMgKjtcIixcbiAgICAgICAgICAnU3RyaWN0LVRyYW5zcG9ydC1TZWN1cml0eSc6ICdtYXgtYWdlPTYzMDcyMDAwOyBpbmNsdWRlU3ViZG9tYWluczsgcHJlbG9hZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcmVzb2x2ZTogeyBhbGlhczogeyB1dGlsOiAndXRpbC8nLCBzdHJlYW06ICdzdHJlYW0tYnJvd3NlcmlmeScgfSB9LCAvLyBzdHJlYW0gcG9seWZpbGwgaXMgbmVlZGVkIGJ5IGxvZ2ZsYXJlXG4gICAgfSk7XG4gIH1cbiAgLy8gY29tbWFuZCA9PT0gJ2J1aWxkJ1xuICByZXR1cm4gZGVmaW5lQ29uZmlnKHtcbiAgICBvcHRpbWl6ZURlcHM6IHtcbiAgICAgIGVzYnVpbGRPcHRpb25zOiB7XG4gICAgICAgIC8vIE5vZGUuanMgZ2xvYmFsIHRvIGJyb3dzZXIgZ2xvYmFsVGhpc1xuICAgICAgICBkZWZpbmU6IHtcbiAgICAgICAgICBnbG9iYWw6ICdnbG9iYWxUaGlzJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICAvLyBidWlsZCBzcGVjaWZpYyBjb25maWdcbiAgICBwbHVnaW5zOiBbcmVhY3QoKSwgdml0ZVRzY29uZmlnUGF0aHMoKSwgc3ZnclBsdWdpbigpXSxcbiAgICBidWlsZDoge1xuICAgICAgLy8gdGhpcyBpcyBuZWVkZWQgYmVjYXVzZSBvZiB0aGlzIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRlanMvdml0ZS9pc3N1ZXMvMjEzOSNpc3N1ZWNvbW1lbnQtMTQwNTYyNDc0NFxuICAgICAgY29tbW9uanNPcHRpb25zOiB7XG4gICAgICAgIGRlZmF1bHRJc01vZHVsZUV4cG9ydHMoaWQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgbW9kdWxlID0gcmVxdWlyZShpZCk7XG4gICAgICAgICAgICBpZiAobW9kdWxlPy5kZWZhdWx0KSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAnYXV0byc7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiAnYXV0byc7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB0cmFuc2Zvcm1NaXhlZEVzTW9kdWxlczogdHJ1ZSxcbiAgICAgIH0sXG4gICAgICBvdXREaXI6ICdidWlsZCcsXG4gICAgICByb2xsdXBPcHRpb25zOiB7XG4gICAgICAgIHBsdWdpbnM6IFtub2RlUG9seWZpbGxzKCdidWZmZXInLCAncHJvY2VzcycpXSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICByZXNvbHZlOiB7IGFsaWFzOiB7IHV0aWw6ICd1dGlsLycsIHN0cmVhbTogJ3N0cmVhbS1icm93c2VyaWZ5JyB9IH0sXG4gIH0pO1xufTtcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7OztBQUVBLFNBQVMsb0JBQWlEO0FBQzFELE9BQU8sV0FBVztBQUVsQixPQUFPLHVCQUF1QjtBQUM5QixPQUFPLGFBQWE7QUFDcEIsT0FBTyxnQkFBZ0I7QUFDdkIsT0FBTyxRQUFRO0FBQ2YsT0FBTyxtQkFBbUI7QUFHMUIsSUFBTyxzQkFBUSxDQUFDLEVBQUUsU0FBUyxLQUFLLE1BQW1DO0FBQ2pFLE1BQUksU0FBUyxVQUFVLFlBQVksU0FBUztBQUMxQyxXQUFPLGFBQWE7QUFBQTtBQUFBLE1BRWxCLFNBQVMsQ0FBQyxNQUFNLEdBQUcsa0JBQWtCLEdBQUcsV0FBVyxDQUFDO0FBQUEsTUFFcEQsY0FBYztBQUFBLFFBQ1osZ0JBQWdCO0FBQUE7QUFBQSxVQUVkLFFBQVE7QUFBQSxZQUNOLFFBQVE7QUFBQSxVQUNWO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFBQSxNQUVBLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxRQUFRLEVBQUU7QUFBQSxNQUNwQyxNQUFNO0FBQUEsUUFDSixTQUFTO0FBQUEsUUFDVCxhQUFhO0FBQUEsUUFDYixZQUFZO0FBQUEsUUFDWixVQUFVO0FBQUEsVUFDUixVQUFVLENBQUMsUUFBUSxRQUFRLE1BQU07QUFBQTtBQUFBLFVBRWpDLFVBQVU7QUFBQTtBQUFBLFVBQ1YsU0FBUyxDQUFDLGlCQUFpQixlQUFlO0FBQUEsUUFDNUM7QUFBQSxRQUNBLEtBQUs7QUFBQSxNQUNQO0FBQUEsSUFDRixDQUFDO0FBQUEsRUFDSDtBQUNBLE1BQUksWUFBWSxTQUFTO0FBQ3ZCLFdBQU8sYUFBYTtBQUFBO0FBQUEsTUFFbEIsU0FBUyxDQUFDLE1BQU0sR0FBRyxrQkFBa0IsR0FBRyxXQUFXLEdBQUcsUUFBUSxFQUFFLFlBQVksS0FBSyxDQUFDLENBQUM7QUFBQSxNQUNuRixjQUFjO0FBQUEsUUFDWixnQkFBZ0I7QUFBQTtBQUFBLFVBRWQsUUFBUTtBQUFBLFlBQ04sUUFBUTtBQUFBLFVBQ1Y7QUFBQSxRQUNGO0FBQUEsTUFDRjtBQUFBLE1BQ0EsUUFBUTtBQUFBLFFBQ04sTUFBTTtBQUFBLFFBQ04sTUFBTTtBQUFBLFFBQ04sT0FBTztBQUFBLFVBQ0wsS0FBSyxHQUFHLGFBQWEsMkNBQTJDO0FBQUEsVUFDaEUsTUFBTSxHQUFHLGFBQWEsdUNBQXVDO0FBQUEsUUFDL0Q7QUFBQSxRQUNBLFNBQVM7QUFBQSxVQUNQLDBCQUEwQjtBQUFBLFVBQzFCLG9CQUFvQjtBQUFBLFVBQ3BCLG1CQUFtQjtBQUFBLFVBQ25CLDJCQUNFO0FBQUEsVUFDRiw2QkFBNkI7QUFBQSxRQUMvQjtBQUFBLE1BQ0Y7QUFBQSxNQUNBLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxTQUFTLFFBQVEsb0JBQW9CLEVBQUU7QUFBQTtBQUFBLElBQ25FLENBQUM7QUFBQSxFQUNIO0FBRUEsU0FBTyxhQUFhO0FBQUEsSUFDbEIsY0FBYztBQUFBLE1BQ1osZ0JBQWdCO0FBQUE7QUFBQSxRQUVkLFFBQVE7QUFBQSxVQUNOLFFBQVE7QUFBQSxRQUNWO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQTtBQUFBLElBRUEsU0FBUyxDQUFDLE1BQU0sR0FBRyxrQkFBa0IsR0FBRyxXQUFXLENBQUM7QUFBQSxJQUNwRCxPQUFPO0FBQUE7QUFBQSxNQUVMLGlCQUFpQjtBQUFBLFFBQ2YsdUJBQXVCLElBQUk7QUFDekIsY0FBSTtBQUNGLGtCQUFNLFNBQVMsVUFBUSxFQUFFO0FBQ3pCLGdCQUFJLFFBQVEsU0FBUztBQUNuQixxQkFBTztBQUFBLFlBQ1Q7QUFDQSxtQkFBTztBQUFBLFVBQ1QsU0FBUyxPQUFPO0FBQ2QsbUJBQU87QUFBQSxVQUNUO0FBQUEsUUFDRjtBQUFBLFFBQ0EseUJBQXlCO0FBQUEsTUFDM0I7QUFBQSxNQUNBLFFBQVE7QUFBQSxNQUNSLGVBQWU7QUFBQSxRQUNiLFNBQVMsQ0FBQyxjQUFjLFVBQVUsU0FBUyxDQUFDO0FBQUEsTUFDOUM7QUFBQSxJQUNGO0FBQUEsSUFDQSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sU0FBUyxRQUFRLG9CQUFvQixFQUFFO0FBQUEsRUFDbkUsQ0FBQztBQUNIOyIsCiAgIm5hbWVzIjogW10KfQo= From b71cf581440ecbb473a8a0c7abead28e1bc42ee3 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Thu, 22 Feb 2024 21:36:55 +0530 Subject: [PATCH 35/36] moved matchmedia mock function to mocks --- src/App.test.tsx | 2 +- src/components/UI/Form/EmojiInput/Editor.test.tsx | 2 +- src/components/UI/Form/EmojiInput/EmojiInput.test.tsx | 2 +- src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx | 2 +- src/components/UI/MessageDialog/MessageDialog.test.tsx | 2 +- src/containers/Chat/Chat.test.tsx | 2 +- .../ConversationList/ConversationList.test.tsx | 2 +- src/containers/Chat/ChatInterface/ChatInterface.test.tsx | 2 +- src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx | 2 +- src/containers/Chat/ChatMessages/ChatMessages.test.tsx | 2 +- src/containers/InteractiveMessage/InteractiveMessage.test.tsx | 2 +- src/containers/Template/Form/HSM/HSM.test.tsx | 2 +- src/containers/Template/Form/SpeedSend/SpeedSend.test.tsx | 2 +- src/containers/Template/Form/Template.test.tsx | 2 +- src/{ => mocks}/matchMediaMock.ts | 0 src/routes/AuthenticatedRoute/AuthenticatedRoute.test.tsx | 2 +- 16 files changed, 15 insertions(+), 15 deletions(-) rename src/{ => mocks}/matchMediaMock.ts (100%) diff --git a/src/App.test.tsx b/src/App.test.tsx index f76a56255..476c38a63 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,4 +1,4 @@ -import './matchMediaMock'; +import 'mocks/matchMediaMock'; import { MemoryRouter } from 'react-router-dom'; import { MockedProvider } from '@apollo/client/testing'; import { waitFor, render } from '@testing-library/react'; diff --git a/src/components/UI/Form/EmojiInput/Editor.test.tsx b/src/components/UI/Form/EmojiInput/Editor.test.tsx index a32d5208e..3f2f58504 100644 --- a/src/components/UI/Form/EmojiInput/Editor.test.tsx +++ b/src/components/UI/Form/EmojiInput/Editor.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { render } from '@testing-library/react'; import { Editor } from './Editor'; import { LexicalWrapper } from 'common/LexicalWrapper'; diff --git a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx index 830e75462..9745fa768 100644 --- a/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx +++ b/src/components/UI/Form/EmojiInput/EmojiInput.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { render } from '@testing-library/react'; import { EmojiInput } from './EmojiInput'; import userEvent from '@testing-library/user-event'; diff --git a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx index 9076aa818..79304f294 100644 --- a/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx +++ b/src/components/UI/Form/WhatsAppEditor/WhatsAppEditor.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { vi } from 'vitest'; diff --git a/src/components/UI/MessageDialog/MessageDialog.test.tsx b/src/components/UI/MessageDialog/MessageDialog.test.tsx index 7c9524c68..b600f9c78 100644 --- a/src/components/UI/MessageDialog/MessageDialog.test.tsx +++ b/src/components/UI/MessageDialog/MessageDialog.test.tsx @@ -1,4 +1,4 @@ -import '../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { fireEvent, render } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; diff --git a/src/containers/Chat/Chat.test.tsx b/src/containers/Chat/Chat.test.tsx index dac0a8912..c5b4f0485 100644 --- a/src/containers/Chat/Chat.test.tsx +++ b/src/containers/Chat/Chat.test.tsx @@ -1,4 +1,4 @@ -import '../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { cleanup, render, waitFor } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; diff --git a/src/containers/Chat/ChatConversations/ConversationList/ConversationList.test.tsx b/src/containers/Chat/ChatConversations/ConversationList/ConversationList.test.tsx index ae6d000c7..d0480dc7c 100644 --- a/src/containers/Chat/ChatConversations/ConversationList/ConversationList.test.tsx +++ b/src/containers/Chat/ChatConversations/ConversationList/ConversationList.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { BrowserRouter as Router } from 'react-router-dom'; import { render, waitFor, screen, fireEvent } from '@testing-library/react'; import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'; diff --git a/src/containers/Chat/ChatInterface/ChatInterface.test.tsx b/src/containers/Chat/ChatInterface/ChatInterface.test.tsx index bd23ae937..e960ffcc8 100644 --- a/src/containers/Chat/ChatInterface/ChatInterface.test.tsx +++ b/src/containers/Chat/ChatInterface/ChatInterface.test.tsx @@ -1,4 +1,4 @@ -import '../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { MemoryRouter } from 'react-router-dom'; import { cleanup, render } from '@testing-library/react'; import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'; diff --git a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx index 539ecf80e..b0bef2fa6 100644 --- a/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatInput/ChatInput.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { MockedProvider } from '@apollo/client/testing'; import { render, waitFor, fireEvent } from '@testing-library/react'; import { vi } from 'vitest'; diff --git a/src/containers/Chat/ChatMessages/ChatMessages.test.tsx b/src/containers/Chat/ChatMessages/ChatMessages.test.tsx index 4c63d8490..ba8f6d0bf 100644 --- a/src/containers/Chat/ChatMessages/ChatMessages.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessages.test.tsx @@ -1,4 +1,4 @@ -import '../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { render, screen, act } from '@testing-library/react'; import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'; import { fireEvent, waitFor } from '@testing-library/dom'; diff --git a/src/containers/InteractiveMessage/InteractiveMessage.test.tsx b/src/containers/InteractiveMessage/InteractiveMessage.test.tsx index 7594603e4..de3cfb59c 100644 --- a/src/containers/InteractiveMessage/InteractiveMessage.test.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessage.test.tsx @@ -1,4 +1,4 @@ -import '../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { render, screen, waitFor, fireEvent } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import axios from 'axios'; diff --git a/src/containers/Template/Form/HSM/HSM.test.tsx b/src/containers/Template/Form/HSM/HSM.test.tsx index 7d5579560..50d73488d 100644 --- a/src/containers/Template/Form/HSM/HSM.test.tsx +++ b/src/containers/Template/Form/HSM/HSM.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { render, waitFor, within, fireEvent } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import userEvent from '@testing-library/user-event'; diff --git a/src/containers/Template/Form/SpeedSend/SpeedSend.test.tsx b/src/containers/Template/Form/SpeedSend/SpeedSend.test.tsx index 2faf7e004..a89437286 100644 --- a/src/containers/Template/Form/SpeedSend/SpeedSend.test.tsx +++ b/src/containers/Template/Form/SpeedSend/SpeedSend.test.tsx @@ -1,4 +1,4 @@ -import '../../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { render, within, fireEvent, cleanup, waitFor } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; import { MockedProvider } from '@apollo/client/testing'; diff --git a/src/containers/Template/Form/Template.test.tsx b/src/containers/Template/Form/Template.test.tsx index 92df577e0..eb10ffa07 100644 --- a/src/containers/Template/Form/Template.test.tsx +++ b/src/containers/Template/Form/Template.test.tsx @@ -1,4 +1,4 @@ -import '../../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { render, waitFor, cleanup, fireEvent } from '@testing-library/react'; import { MockedProvider } from '@apollo/client/testing'; import { BrowserRouter } from 'react-router-dom'; diff --git a/src/matchMediaMock.ts b/src/mocks/matchMediaMock.ts similarity index 100% rename from src/matchMediaMock.ts rename to src/mocks/matchMediaMock.ts diff --git a/src/routes/AuthenticatedRoute/AuthenticatedRoute.test.tsx b/src/routes/AuthenticatedRoute/AuthenticatedRoute.test.tsx index 387e5b9ae..2ea4021d8 100644 --- a/src/routes/AuthenticatedRoute/AuthenticatedRoute.test.tsx +++ b/src/routes/AuthenticatedRoute/AuthenticatedRoute.test.tsx @@ -1,4 +1,4 @@ -import '../../matchMediaMock'; +import 'mocks/matchMediaMock'; import { Suspense } from 'react'; import { render, waitFor } from '@testing-library/react'; import { BrowserRouter } from 'react-router-dom'; From 0756adf7bc2ee20283c0e33627c6e2576abc87e9 Mon Sep 17 00:00:00 2001 From: akanshaaaa19 Date: Mon, 26 Feb 2024 11:04:34 +0530 Subject: [PATCH 36/36] fix: padding of editor component --- src/components/UI/Form/EmojiInput/Editor.module.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/UI/Form/EmojiInput/Editor.module.css b/src/components/UI/Form/EmojiInput/Editor.module.css index ad3d5b220..646173caa 100644 --- a/src/components/UI/Form/EmojiInput/Editor.module.css +++ b/src/components/UI/Form/EmojiInput/Editor.module.css @@ -12,7 +12,7 @@ border-radius: 12px; height: 10rem; position: relative; - padding: 0 1rem 1rem 1rem; + padding: 1rem; position: relative; display: block; border-bottom-left-radius: 10px; @@ -44,6 +44,7 @@ .EditorInput p { overflow: scroll !important; + margin: 0 !important; } .EditorWrapper { @@ -66,7 +67,7 @@ border-radius: 12px; height: 10rem; position: relative; - padding: 0 1rem 1rem 1rem; + padding: 1rem; position: relative; display: block; border-bottom-left-radius: 10px;