From 2eb42636086d214539f16e82bab23f96fcbe131e Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Mon, 6 Nov 2023 21:24:44 +0000 Subject: [PATCH 01/16] update copy icon --- src/assets/images/icons/Duplicate.svg | 25 +++++++++++++++++++ src/assets/images/icons/Flow/Duplicate.svg | 16 ------------ src/containers/Flow/FlowList/FlowList.tsx | 2 +- .../InteractiveMessageList.tsx | 2 +- .../Trigger/TriggerList/TriggerList.tsx | 2 +- 5 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 src/assets/images/icons/Duplicate.svg delete mode 100644 src/assets/images/icons/Flow/Duplicate.svg diff --git a/src/assets/images/icons/Duplicate.svg b/src/assets/images/icons/Duplicate.svg new file mode 100644 index 000000000..9337e4c2e --- /dev/null +++ b/src/assets/images/icons/Duplicate.svg @@ -0,0 +1,25 @@ + + + + Make a copy + Create a copy using this action. + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/icons/Flow/Duplicate.svg b/src/assets/images/icons/Flow/Duplicate.svg deleted file mode 100644 index 6d55607bf..000000000 --- a/src/assets/images/icons/Flow/Duplicate.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - Copy Flow - Created with Sketch. - - - - - - - - - - - \ No newline at end of file diff --git a/src/containers/Flow/FlowList/FlowList.tsx b/src/containers/Flow/FlowList/FlowList.tsx index 4e40a75e0..e5451ab6d 100644 --- a/src/containers/Flow/FlowList/FlowList.tsx +++ b/src/containers/Flow/FlowList/FlowList.tsx @@ -6,7 +6,7 @@ import { useLazyQuery, useMutation, useQuery } from '@apollo/client'; import { FormControl, MenuItem, Select } from '@mui/material'; import FlowIcon from 'assets/images/icons/Flow/Dark.svg?react'; -import DuplicateIcon from 'assets/images/icons/Flow/Duplicate.svg?react'; +import DuplicateIcon from 'assets/images/icons/Duplicate.svg?react'; import ExportIcon from 'assets/images/icons/Flow/Export.svg?react'; import ConfigureIcon from 'assets/images/icons/Configure/UnselectedDark.svg?react'; import PinIcon from 'assets/images/icons/Pin/Active.svg?react'; diff --git a/src/containers/InteractiveMessage/InteractiveMessageList/InteractiveMessageList.tsx b/src/containers/InteractiveMessage/InteractiveMessageList/InteractiveMessageList.tsx index 8cf1fb740..523668b33 100644 --- a/src/containers/InteractiveMessage/InteractiveMessageList/InteractiveMessageList.tsx +++ b/src/containers/InteractiveMessage/InteractiveMessageList/InteractiveMessageList.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import InteractiveMessageIcon from 'assets/images/icons/InteractiveMessage/Dark.svg?react'; import DownArrow from 'assets/images/icons/DownArrow.svg?react'; -import DuplicateIcon from 'assets/images/icons/Flow/Duplicate.svg?react'; +import DuplicateIcon from 'assets/images/icons/Duplicate.svg?react'; import { List } from 'containers/List/List'; import { FILTER_INTERACTIVE_MESSAGES, diff --git a/src/containers/Trigger/TriggerList/TriggerList.tsx b/src/containers/Trigger/TriggerList/TriggerList.tsx index a72055949..67d77b739 100644 --- a/src/containers/Trigger/TriggerList/TriggerList.tsx +++ b/src/containers/Trigger/TriggerList/TriggerList.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'; import TriggerIcon from 'assets/images/icons/Trigger/Union.svg?react'; import ClockIcon from 'assets/images/icons/Trigger/Clock.svg?react'; import ClockInactiveIcon from 'assets/images/icons/Trigger/Inactive.svg?react'; -import DuplicateIcon from 'assets/images/icons/Flow/Duplicate.svg?react'; +import DuplicateIcon from 'assets/images/icons/Duplicate.svg?react'; import { TRIGGER_LIST_QUERY, TRIGGER_QUERY_COUNT } from 'graphql/queries/Trigger'; import { DELETE_TRIGGER } from 'graphql/mutations/Trigger'; import { FULL_DATE_FORMAT, dayList } from 'common/constants'; From 4782ad8d68f422e13ed37e6ee8cd6e9f7a68aab0 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Mon, 6 Nov 2023 22:44:12 +0000 Subject: [PATCH 02/16] add copy action for template and speed-send --- src/containers/Template/List/Template.tsx | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/containers/Template/List/Template.tsx b/src/containers/Template/List/Template.tsx index 81aa73601..f5fb97e13 100644 --- a/src/containers/Template/List/Template.tsx +++ b/src/containers/Template/List/Template.tsx @@ -1,10 +1,11 @@ import { useContext, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import moment from 'moment'; import { useTranslation } from 'react-i18next'; import { Checkbox, FormControlLabel } from '@mui/material'; +import { useMutation, useQuery } from '@apollo/client'; import { List } from 'containers/List/List'; -import { useMutation, useQuery } from '@apollo/client'; import { WhatsAppToJsx } from 'common/RichEditor'; import { DATE_TIME_FORMAT, GUPSHUP_ENTERPRISE_SHORTCODE } from 'common/constants'; import { @@ -22,6 +23,7 @@ import DownArrow from 'assets/images/icons/DownArrow.svg?react'; import ApprovedIcon from 'assets/images/icons/Template/Approved.svg?react'; import RejectedIcon from 'assets/images/icons/Template/Rejected.svg?react'; import PendingIcon from 'assets/images/icons/Template/Pending.svg?react'; +import DuplicateIcon from 'assets/images/icons/Duplicate.svg?react'; import { ProviderContext } from 'context/session'; import { copyToClipboardMethod, exportCsvFile, getFileExtension } from 'common/utils'; import Loading from 'components/UI/Layout/Loading/Loading'; @@ -80,6 +82,7 @@ export const Template = ({ const [open, setOpen] = useState(false); const [Id, setId] = useState(''); const { t } = useTranslation(); + const navigate = useNavigate(); const { provider } = useContext(ProviderContext); const [selectedTag, setSelectedTag] = useState(null); @@ -223,6 +226,14 @@ export const Template = ({ } }; + const setCopyDialog = (id: any) => { + let redirectPath = 'speed-send'; + if (isHSM) { + redirectPath = 'template'; + } + navigate(`/${redirectPath}/${id}/edit`, { state: 'copy' }); + }; + const setDialog = (id: string) => { if (Id !== id) { setId(id); @@ -232,7 +243,15 @@ export const Template = ({ } }; + const copyAction = { + label: t('Make a copy'), + icon: , + parameter: 'id', + dialog: setCopyDialog, + }; + let additionalAction: any = () => [ + copyAction, { label: t('Show all languages'), icon: , @@ -286,6 +305,7 @@ export const Template = ({ if (isHSM) { additionalAction = () => [ + copyAction, { label: t('Copy UUID'), icon: , From ba79c6d9e35efee7404c2c0531db3761bde5fe1b Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Mon, 6 Nov 2023 23:19:17 +0000 Subject: [PATCH 03/16] more work on copy action --- src/containers/Template/Form/Template.tsx | 31 +++++++++++++++++++---- src/containers/Template/List/Template.tsx | 4 +-- src/i18n/en/en.json | 6 +++-- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index 8d1057006..d57afd063 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -203,7 +203,21 @@ const Template = ({ const navigate = useNavigate(); const location: any = useLocation(); const params = useParams(); - const isEditForm = !!params.id; + + let isEditing = false; + let mode; + + const isCopyState = location.state === 'copy'; + if (isCopyState) { + queries.updateItemQuery = CREATE_TEMPLATE; + mode = 'copy'; + } else { + queries.updateItemQuery = UPDATE_TEMPLATE; + } + + if (params.id && !isCopyState) { + isEditing = true; + } const { data: tag } = useQuery(GET_TAGS, { variables: {}, @@ -387,7 +401,7 @@ const Template = ({ lang.sort((first: any, second: any) => (first.label > second.label ? 1 : -1)); setLanguageOptions(lang); - if (!isEditForm) setLanguageId(lang[0]); + if (!isEditing) setLanguageId(lang[0]); } }, [languages]); @@ -469,7 +483,7 @@ const Template = ({ const selected = languageOptions.find( ({ label: languageLabel }: any) => languageLabel === value ); - if (selected && isEditForm) { + if (selected && isEditing) { updateTranslation(selected); } else if (selected) { setLanguageId(selected); @@ -484,7 +498,7 @@ const Template = ({ } // create translations only while updating - if (result && isEditForm) { + if (result && isEditing) { updateTranslation(result); } if (result) setLanguageId(result); @@ -1005,13 +1019,18 @@ const Template = ({ return ; } + let copyMessage = t('Copy of the speed send has been created!'); + if (defaultAttribute.isHsm) { + copyMessage = t('Copy of the template has been created!'); + } + return ( ); }; diff --git a/src/containers/Template/List/Template.tsx b/src/containers/Template/List/Template.tsx index f5fb97e13..cf3df953c 100644 --- a/src/containers/Template/List/Template.tsx +++ b/src/containers/Template/List/Template.tsx @@ -251,13 +251,13 @@ export const Template = ({ }; let additionalAction: any = () => [ - copyAction, { label: t('Show all languages'), icon: , parameter: 'id', dialog: setDialog, }, + copyAction, ]; let defaultSortBy; @@ -305,13 +305,13 @@ export const Template = ({ if (isHSM) { additionalAction = () => [ - copyAction, { label: t('Copy UUID'), icon: , parameter: 'id', dialog: copyUuid, }, + copyAction, ]; defaultSortBy = 'STATUS'; appliedFilters = { ...templateFilters, status: filterValue }; diff --git a/src/i18n/en/en.json b/src/i18n/en/en.json index 359f15221..610e51e6d 100644 --- a/src/i18n/en/en.json +++ b/src/i18n/en/en.json @@ -373,6 +373,8 @@ "Message is required.": "Message is required.", "Please enter valid phone number.": "Please enter valid phone number.", "Please enter valid url.": "Please enter valid url.", + "Copy of the speed send has been created!": "", + "Copy of the template has been created!": "", "Submit for Approval": "Submit for Approval", "Create": "Create", "Create Speed Send": "Create Speed Send", @@ -393,6 +395,7 @@ "Change assignee": "Change assignee", "Remarks": "Remarks", "Update ticket": "Update ticket", + "ID": "ID", "Created at": "Created at", "Issue": "Issue", "Opened by": "Opened by", @@ -433,6 +436,5 @@ "Request header": "Request header", "Request JSON": "Request JSON", "Response JSON": "Response JSON", - "Webhook Logs": "Webhook Logs", - "ID": "ID" + "Webhook Logs": "Webhook Logs" } From 18486e9c20e3527fcb8ae2da9fc610a59a067379 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Thu, 9 Nov 2023 22:40:08 +0000 Subject: [PATCH 04/16] code restruturing --- src/containers/Template/Form/Template.tsx | 118 +++++++++++----------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index d57afd063..1211e2dc0 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -204,21 +204,6 @@ const Template = ({ const location: any = useLocation(); const params = useParams(); - let isEditing = false; - let mode; - - const isCopyState = location.state === 'copy'; - if (isCopyState) { - queries.updateItemQuery = CREATE_TEMPLATE; - mode = 'copy'; - } else { - queries.updateItemQuery = UPDATE_TEMPLATE; - } - - if (params.id && !isCopyState) { - isEditing = true; - } - const { data: tag } = useQuery(GET_TAGS, { variables: {}, fetchPolicy: 'network-only', @@ -421,6 +406,65 @@ const Template = ({ } }, [getExample]); + useEffect(() => { + if ((type === '' || type) && attachmentURL) { + validateURL(attachmentURL); + if (getUrlAttachmentAndType) { + getUrlAttachmentAndType(type.id || 'TEXT', { url: attachmentURL }); + } + } + }, [type, attachmentURL]); + + useEffect(() => { + displayWarning(); + }, [type]); + + useEffect(() => { + if (templateType) { + addTemplateButtons(false); + } + }, [templateType]); + + // Removing buttons when checkbox is checked or unchecked + useEffect(() => { + if (getExample) { + const { message }: any = getTemplateAndButton(getPlainTextFromEditor(getExample)); + onExampleChange(message || ''); + } + }, [isAddButtonChecked]); + + // Converting buttons to template and vice-versa to show realtime update on simulator + useEffect(() => { + if (templateButtons.length > 0) { + const parse = convertButtonsToTemplate(templateButtons, templateType); + + const parsedText = parse.length ? `| ${parse.join(' | ')}` : null; + + const { message }: any = getTemplateAndButton(getPlainTextFromEditor(example)); + + const sampleText: any = parsedText && message + parsedText; + + if (sampleText) { + onExampleChange(sampleText); + } + } + }, [templateButtons]); + + let isEditing = false; + let mode; + + const isCopyState = location.state === 'copy'; + if (isCopyState) { + queries.updateItemQuery = CREATE_TEMPLATE; + mode = 'copy'; + } else { + queries.updateItemQuery = UPDATE_TEMPLATE; + } + + if (params.id && !isCopyState) { + isEditing = true; + } + const validateTitle = (value: any) => { let error; if (value) { @@ -518,15 +562,6 @@ const Template = ({ } }; - useEffect(() => { - if ((type === '' || type) && attachmentURL) { - validateURL(attachmentURL); - if (getUrlAttachmentAndType) { - getUrlAttachmentAndType(type.id || 'TEXT', { url: attachmentURL }); - } - } - }, [type, attachmentURL]); - const displayWarning = () => { if (type && type.id === 'STICKER') { setWarning( @@ -550,10 +585,6 @@ const Template = ({ } }; - useEffect(() => { - displayWarning(); - }, [type]); - let timer: any = null; const attachmentField = [ { @@ -684,12 +715,6 @@ const Template = ({ setTemplateButtons(result); }; - useEffect(() => { - if (templateType) { - addTemplateButtons(false); - } - }, [templateType]); - const getTemplateAndButton = (text: string) => { const exp = /(\|\s\[)|(\|\[)/; const areButtonsPresent = text.search(exp); @@ -705,31 +730,6 @@ const Template = ({ return { message, buttons }; }; - // Removing buttons when checkbox is checked or unchecked - useEffect(() => { - if (getExample) { - const { message }: any = getTemplateAndButton(getPlainTextFromEditor(getExample)); - onExampleChange(message || ''); - } - }, [isAddButtonChecked]); - - // Converting buttons to template and vice-versa to show realtime update on simulator - useEffect(() => { - if (templateButtons.length > 0) { - const parse = convertButtonsToTemplate(templateButtons, templateType); - - const parsedText = parse.length ? `| ${parse.join(' | ')}` : null; - - const { message }: any = getTemplateAndButton(getPlainTextFromEditor(example)); - - const sampleText: any = parsedText && message + parsedText; - - if (sampleText) { - onExampleChange(sampleText); - } - } - }, [templateButtons]); - const handeInputChange = (event: any, row: any, index: any, eventType: any) => { const { value } = event.target; const obj = { ...row }; From b6a9dc983031a275cce702152e70976d63e5a582 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Thu, 9 Nov 2023 23:15:38 +0000 Subject: [PATCH 05/16] console warning fixes --- src/containers/Template/Form/Template.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index 1211e2dc0..7cc450d0e 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -187,7 +187,7 @@ const Template = ({ const [language, setLanguageId] = useState({}); const [type, setType] = useState(null); const [translations, setTranslations] = useState(); - const [attachmentURL, setAttachmentURL] = useState(); + const [attachmentURL, setAttachmentURL] = useState(''); const [languageOptions, setLanguageOptions] = useState([]); const [isActive, setIsActive] = useState(true); const [validatingURL, setValidatingURL] = useState(false); From 9f7432252eaa17f9eca3020c5d082c449e30bde8 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Thu, 9 Nov 2023 23:19:21 +0000 Subject: [PATCH 06/16] more clean up --- src/containers/Template/Form/Template.tsx | 42 +++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index 7cc450d0e..8e34f76e4 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -209,6 +209,27 @@ const Template = ({ fetchPolicy: 'network-only', }); + const { data: languages } = useQuery(USER_LANGUAGES, { + variables: { opts: { order: 'ASC' } }, + }); + + const [getSessionTemplates, { data: sessionTemplates }] = useLazyQuery(FILTER_TEMPLATES, { + variables: { + filter: { languageId: language ? parseInt(language.id, 10) : null }, + opts: { + order: 'ASC', + limit: null, + offset: 0, + }, + }, + }); + + const [getSessionTemplate, { data: template, loading: templateLoading }] = + useLazyQuery(GET_TEMPLATE); + + // create media for attachment + const [createMediaMessage] = useMutation(CREATE_MEDIA_MESSAGE); + const states = { language, label, @@ -352,27 +373,6 @@ const Template = ({ } }; - const { data: languages } = useQuery(USER_LANGUAGES, { - variables: { opts: { order: 'ASC' } }, - }); - - const [getSessionTemplates, { data: sessionTemplates }] = useLazyQuery(FILTER_TEMPLATES, { - variables: { - filter: { languageId: language ? parseInt(language.id, 10) : null }, - opts: { - order: 'ASC', - limit: null, - offset: 0, - }, - }, - }); - - const [getSessionTemplate, { data: template, loading: templateLoading }] = - useLazyQuery(GET_TEMPLATE); - - // create media for attachment - const [createMediaMessage] = useMutation(CREATE_MEDIA_MESSAGE); - useEffect(() => { if (params.id) { getSessionTemplate({ variables: { id: params.id } }); From 13209826e00b605cba21e0a7a028c83ab5c7adc5 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Thu, 9 Nov 2023 23:42:28 +0000 Subject: [PATCH 07/16] code restructuring and fixes --- src/containers/Template/Form/Template.tsx | 203 +++++++++++----------- 1 file changed, 102 insertions(+), 101 deletions(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index 8e34f76e4..18cf4ce0c 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -204,25 +204,41 @@ const Template = ({ const location: any = useLocation(); const params = useParams(); - const { data: tag } = useQuery(GET_TAGS, { + let isEditing = false; + let mode; + + const isCopyState = location.state === 'copy'; + if (isCopyState) { + queries.updateItemQuery = CREATE_TEMPLATE; + mode = 'copy'; + } else { + queries.updateItemQuery = UPDATE_TEMPLATE; + } + + if (params.id && !isCopyState) { + isEditing = true; + } + + const { data: tag, loading: tagLoading } = useQuery(GET_TAGS, { variables: {}, fetchPolicy: 'network-only', }); - const { data: languages } = useQuery(USER_LANGUAGES, { + const { data: languages, loading: languageLoading } = useQuery(USER_LANGUAGES, { variables: { opts: { order: 'ASC' } }, }); - const [getSessionTemplates, { data: sessionTemplates }] = useLazyQuery(FILTER_TEMPLATES, { - variables: { - filter: { languageId: language ? parseInt(language.id, 10) : null }, - opts: { - order: 'ASC', - limit: null, - offset: 0, + const [getSessionTemplates, { data: sessionTemplates, loading: sessionTemplateLoading }] = + useLazyQuery(FILTER_TEMPLATES, { + variables: { + filter: { languageId: language ? parseInt(language.id, 10) : null }, + opts: { + order: 'ASC', + limit: null, + offset: 0, + }, }, - }, - }); + }); const [getSessionTemplate, { data: template, loading: templateLoading }] = useLazyQuery(GET_TEMPLATE); @@ -373,6 +389,79 @@ const Template = ({ } }; + const displayWarning = () => { + if (type && type.id === 'STICKER') { + setWarning( +
+
    +
  1. {t('Animated stickers are not supported.')}
  2. +
  3. {t('Captions along with stickers are not supported.')}
  4. +
+
+ ); + } else if (type && type.id === 'AUDIO') { + setWarning( +
+
    +
  1. {t('Captions along with audio are not supported.')}
  2. +
+
+ ); + } else { + setWarning(null); + } + }; + + const validateURL = (value: string) => { + if (value && type) { + setValidatingURL(true); + validateMedia(value, type.id, false).then((response: any) => { + if (!response.data.is_valid) { + setIsUrlValid(response.data.message); + } else { + setIsUrlValid(''); + } + setValidatingURL(false); + }); + } + }; + + const addTemplateButtons = (addFromTemplate: boolean = true) => { + let buttons: any = []; + const buttonType: any = { + QUICK_REPLY: { value: '' }, + CALL_TO_ACTION: { type: '', title: '', value: '' }, + }; + + if (templateType) { + buttons = addFromTemplate + ? [...templateButtons, buttonType[templateType]] + : [buttonType[templateType]]; + } + + setTemplateButtons(buttons); + }; + + const removeTemplateButtons = (index: number) => { + const result = templateButtons.filter((val, idx) => idx !== index); + setTemplateButtons(result); + }; + + const getTemplateAndButton = (text: string) => { + const exp = /(\|\s\[)|(\|\[)/; + const areButtonsPresent = text.search(exp); + + let message: any = text; + let buttons: any = null; + + if (areButtonsPresent !== -1) { + buttons = text.substr(areButtonsPresent); + message = text.substr(0, areButtonsPresent); + } + + return { message, buttons }; + }; + useEffect(() => { if (params.id) { getSessionTemplate({ variables: { id: params.id } }); @@ -450,19 +539,8 @@ const Template = ({ } }, [templateButtons]); - let isEditing = false; - let mode; - - const isCopyState = location.state === 'copy'; - if (isCopyState) { - queries.updateItemQuery = CREATE_TEMPLATE; - mode = 'copy'; - } else { - queries.updateItemQuery = UPDATE_TEMPLATE; - } - - if (params.id && !isCopyState) { - isEditing = true; + if (languageLoading || templateLoading || tagLoading || sessionTemplateLoading) { + return ; } const validateTitle = (value: any) => { @@ -548,43 +626,6 @@ const Template = ({ if (result) setLanguageId(result); }; - const validateURL = (value: string) => { - if (value && type) { - setValidatingURL(true); - validateMedia(value, type.id, false).then((response: any) => { - if (!response.data.is_valid) { - setIsUrlValid(response.data.message); - } else { - setIsUrlValid(''); - } - setValidatingURL(false); - }); - } - }; - - const displayWarning = () => { - if (type && type.id === 'STICKER') { - setWarning( -
-
    -
  1. {t('Animated stickers are not supported.')}
  2. -
  3. {t('Captions along with stickers are not supported.')}
  4. -
-
- ); - } else if (type && type.id === 'AUDIO') { - setWarning( -
-
    -
  1. {t('Captions along with audio are not supported.')}
  2. -
-
- ); - } else { - setWarning(null); - } - }; - let timer: any = null; const attachmentField = [ { @@ -694,42 +735,6 @@ const Template = ({ }, ]; - const addTemplateButtons = (addFromTemplate: boolean = true) => { - let buttons: any = []; - const buttonType: any = { - QUICK_REPLY: { value: '' }, - CALL_TO_ACTION: { type: '', title: '', value: '' }, - }; - - if (templateType) { - buttons = addFromTemplate - ? [...templateButtons, buttonType[templateType]] - : [buttonType[templateType]]; - } - - setTemplateButtons(buttons); - }; - - const removeTemplateButtons = (index: number) => { - const result = templateButtons.filter((val, idx) => idx !== index); - setTemplateButtons(result); - }; - - const getTemplateAndButton = (text: string) => { - const exp = /(\|\s\[)|(\|\[)/; - const areButtonsPresent = text.search(exp); - - let message: any = text; - let buttons: any = null; - - if (areButtonsPresent !== -1) { - buttons = text.substr(areButtonsPresent); - message = text.substr(0, areButtonsPresent); - } - - return { message, buttons }; - }; - const handeInputChange = (event: any, row: any, index: any, eventType: any) => { const { value } = event.target; const obj = { ...row }; @@ -1015,10 +1020,6 @@ const Template = ({ } }; - if (languageOptions.length < 1 || templateLoading) { - return ; - } - let copyMessage = t('Copy of the speed send has been created!'); if (defaultAttribute.isHsm) { copyMessage = t('Copy of the template has been created!'); From c96f46537abd8a667f71efc88481b3dad79150a3 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Tue, 14 Nov 2023 23:17:13 +0000 Subject: [PATCH 08/16] fixes for copy reloading --- src/containers/Template/Form/Template.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index 18cf4ce0c..6cecca0a1 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -278,7 +278,7 @@ const Template = ({ hasButtons, }: any) => { if (languageOptions.length > 0 && languageIdValue) { - if (location.state) { + if (location.state && location.state !== 'copy') { const selectedLangauge = languageOptions.find( (lang: any) => lang.label === location.state.language ); From 300f6da78182162a7abeff81cbe9b75b4fe8da2f Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Thu, 16 Nov 2023 23:53:16 +0000 Subject: [PATCH 09/16] test fixes --- src/containers/Template/Form/HSM/HSM.test.tsx | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/containers/Template/Form/HSM/HSM.test.tsx b/src/containers/Template/Form/HSM/HSM.test.tsx index 8bb04964d..4595225c8 100644 --- a/src/containers/Template/Form/HSM/HSM.test.tsx +++ b/src/containers/Template/Form/HSM/HSM.test.tsx @@ -48,21 +48,28 @@ describe('Add mode', () => { const { queryByText } = within(container.querySelector('form') as HTMLElement); const button: any = queryByText('Submit for Approval'); await user.click(button); + + // we should have 2 errors await waitFor(() => { expect(queryByText('Title is required.')).toBeInTheDocument(); expect(queryByText('Message is required.')).toBeInTheDocument(); }); - // we should have 2 errors - - fireEvent.change(container.querySelector('input[name="label"]') as HTMLInputElement, { - target: { - value: - 'We are not allowing a really long title, and we should trigger validation for this.', - }, + await waitFor(() => { + expect(getByText('Add a new HSM Template')).toBeInTheDocument(); + fireEvent.change(container.querySelector('input[name="label"]') as HTMLInputElement, { + target: { + value: + 'We are not allowing a really long title, and we should trigger validation for this.', + }, + }); }); + + await user.click(button); // we should still have 2 errors - expect(queryByText('Title is required.')).toBeInTheDocument(); - expect(queryByText('Message is required.')).toBeInTheDocument(); + await waitFor(() => { + expect(queryByText('Title length is too long.')).toBeInTheDocument(); + expect(queryByText('Message is required.')).toBeInTheDocument(); + }); }); }); From 67dd42fb3f4b922c79badde8e550008636270db7 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Fri, 17 Nov 2023 00:47:49 +0000 Subject: [PATCH 10/16] test fixes --- src/containers/Template/Form/HSM/HSM.test.tsx | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/containers/Template/Form/HSM/HSM.test.tsx b/src/containers/Template/Form/HSM/HSM.test.tsx index 4595225c8..20ea17961 100644 --- a/src/containers/Template/Form/HSM/HSM.test.tsx +++ b/src/containers/Template/Form/HSM/HSM.test.tsx @@ -55,21 +55,23 @@ describe('Add mode', () => { expect(queryByText('Message is required.')).toBeInTheDocument(); }); - await waitFor(() => { - expect(getByText('Add a new HSM Template')).toBeInTheDocument(); - fireEvent.change(container.querySelector('input[name="label"]') as HTMLInputElement, { - target: { - value: - 'We are not allowing a really long title, and we should trigger validation for this.', - }, - }); - }); + // length validation is not working. Basically setting of + // text field value is not working hence, commenting + // below for now - await user.click(button); - // we should still have 2 errors - await waitFor(() => { - expect(queryByText('Title length is too long.')).toBeInTheDocument(); - expect(queryByText('Message is required.')).toBeInTheDocument(); - }); + // fireEvent.change(container.querySelector('input[name="label"]') as HTMLInputElement, { + // target: { + // value: + // 'We are not allowing a really long title, and we should trigger validation for this.', + // }, + // }); + + // await user.click(button); + + // // we should still have 2 errors + // await waitFor(() => { + // expect(queryByText('Title length is too long.')).toBeInTheDocument(); + // expect(queryByText('Message is required.')).toBeInTheDocument(); + // }); }); }); From f25a2a1c9671ae58872fa027c4ec978997021f2d Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Fri, 24 Nov 2023 23:49:46 +0000 Subject: [PATCH 11/16] remove unnecessary validations --- src/containers/Template/Form/Template.tsx | 30 ----------------------- 1 file changed, 30 deletions(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index 6cecca0a1..e0ee0a341 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -182,7 +182,6 @@ const Template = ({ const [label, setLabel] = useState(''); const [body, setBody] = useState(EditorState.createEmpty()); const [example, setExample] = useState(EditorState.createEmpty()); - const [filterLabel, setFilterLabel] = useState(''); const [shortcode, setShortcode] = useState(''); const [language, setLanguageId] = useState({}); const [type, setType] = useState(null); @@ -479,12 +478,6 @@ const Template = ({ } }, [languages]); - useEffect(() => { - if (filterLabel && language && language.id) { - getSessionTemplates(); - } - }, [filterLabel, language, getSessionTemplates]); - useEffect(() => { setShortcode(getShortcode); }, [getShortcode]); @@ -543,28 +536,6 @@ const Template = ({ return ; } - const validateTitle = (value: any) => { - let error; - if (value) { - setFilterLabel(value); - let found = []; - if (sessionTemplates) { - if (getSessionTemplatesCallBack) { - getSessionTemplatesCallBack(sessionTemplates); - } - // need to check exact title - found = sessionTemplates.sessionTemplates.filter((search: any) => search.label === value); - if (params.id && found.length > 0) { - found = found.filter((search: any) => search.id !== params.id); - } - } - if (found.length > 0) { - error = t('Title already exists.'); - } - } - return error; - }; - const updateTranslation = (value: any) => { const translationId = value.id; // restore if selected language is same as template @@ -709,7 +680,6 @@ const Template = ({ component: Input, name: 'label', placeholder: `${t('Title')}*`, - validate: validateTitle, disabled: !!(defaultAttribute.isHsm && params.id), helperText: defaultAttribute.isHsm ? t('Define what use case does this template serve eg. OTP, optin, activity preference') From b1d3d824cd71a62560da07d28cea9b018051b502 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Fri, 24 Nov 2023 23:56:21 +0000 Subject: [PATCH 12/16] deepscan and test fixes --- src/containers/Template/Form/HSM/HSM.test.tsx | 28 ++++++++----------- src/containers/Template/Form/Template.tsx | 12 -------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/containers/Template/Form/HSM/HSM.test.tsx b/src/containers/Template/Form/HSM/HSM.test.tsx index 20ea17961..083ea5a70 100644 --- a/src/containers/Template/Form/HSM/HSM.test.tsx +++ b/src/containers/Template/Form/HSM/HSM.test.tsx @@ -55,23 +55,19 @@ describe('Add mode', () => { expect(queryByText('Message is required.')).toBeInTheDocument(); }); - // length validation is not working. Basically setting of - // text field value is not working hence, commenting - // below for now - - // fireEvent.change(container.querySelector('input[name="label"]') as HTMLInputElement, { - // target: { - // value: - // 'We are not allowing a really long title, and we should trigger validation for this.', - // }, - // }); + fireEvent.change(container.querySelector('input[name="label"]') as HTMLInputElement, { + target: { + value: + 'We are not allowing a really long title, and we should trigger validation for this.', + }, + }); - // await user.click(button); + await user.click(button); - // // we should still have 2 errors - // await waitFor(() => { - // expect(queryByText('Title length is too long.')).toBeInTheDocument(); - // expect(queryByText('Message is required.')).toBeInTheDocument(); - // }); + // we should still have 2 errors + await waitFor(() => { + expect(queryByText('Title length is too long.')).toBeInTheDocument(); + expect(queryByText('Message is required.')).toBeInTheDocument(); + }); }); }); diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index e0ee0a341..235a1b19a 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -227,18 +227,6 @@ const Template = ({ variables: { opts: { order: 'ASC' } }, }); - const [getSessionTemplates, { data: sessionTemplates, loading: sessionTemplateLoading }] = - useLazyQuery(FILTER_TEMPLATES, { - variables: { - filter: { languageId: language ? parseInt(language.id, 10) : null }, - opts: { - order: 'ASC', - limit: null, - offset: 0, - }, - }, - }); - const [getSessionTemplate, { data: template, loading: templateLoading }] = useLazyQuery(GET_TEMPLATE); From e52603da7394e21b031f70cf5b3ca0b1773f2bb5 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Fri, 24 Nov 2023 23:57:43 +0000 Subject: [PATCH 13/16] typo fixes --- src/containers/Template/Form/Template.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index 235a1b19a..d6224764c 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -520,7 +520,7 @@ const Template = ({ } }, [templateButtons]); - if (languageLoading || templateLoading || tagLoading || sessionTemplateLoading) { + if (languageLoading || templateLoading || tagLoading) { return ; } From 41ca955108fc82f26f7efd062f077fb75cba44f7 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Sat, 25 Nov 2023 00:20:04 +0000 Subject: [PATCH 14/16] deepscan fixes --- src/containers/Template/Form/Template.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index d6224764c..e28c1f4cb 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -13,7 +13,7 @@ import { EmojiInput } from 'components/UI/Form/EmojiInput/EmojiInput'; import { AutoComplete } from 'components/UI/Form/AutoComplete/AutoComplete'; import { Checkbox } from 'components/UI/Form/Checkbox/Checkbox'; import { LanguageBar } from 'components/UI/LanguageBar/LanguageBar'; -import { GET_TEMPLATE, FILTER_TEMPLATES } from 'graphql/queries/Template'; +import { GET_TEMPLATE } from 'graphql/queries/Template'; import { CREATE_MEDIA_MESSAGE } from 'graphql/mutations/Chat'; import { USER_LANGUAGES } from 'graphql/queries/Organization'; import { GET_TAGS } from 'graphql/queries/Tags'; From f2de412c8d6b66bb236cdac1ea75972364082c99 Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Wed, 29 Nov 2023 00:22:14 +0000 Subject: [PATCH 15/16] allow editing in copy mode --- src/containers/Template/Form/HSM/HSM.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/containers/Template/Form/HSM/HSM.tsx b/src/containers/Template/Form/HSM/HSM.tsx index b756355ef..67a2f5825 100644 --- a/src/containers/Template/Form/HSM/HSM.tsx +++ b/src/containers/Template/Form/HSM/HSM.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import { useQuery } from '@apollo/client'; import { EditorState } from 'draft-js'; import { useTranslation } from 'react-i18next'; -import { useParams } from 'react-router-dom'; +import { useParams, useLocation } from 'react-router-dom'; import Loading from 'components/UI/Layout/Loading/Loading'; import TemplateIcon from 'assets/images/icons/Template/UnselectedDark.svg?react'; import { GET_HSM_CATEGORIES } from 'graphql/queries/Template'; @@ -32,6 +32,7 @@ export const HSM = () => { const [category, setCategory] = useState({ label: '', id: '' }); const { t } = useTranslation(); const params = useParams(); + const location: any = useLocation(); const { data: categoryList, loading } = useQuery(GET_HSM_CATEGORIES); @@ -109,8 +110,9 @@ export const HSM = () => { setSampleMessages(message); }; + const isCopyState = location.state === 'copy'; let disabled = false; - if (params.id) { + if (params.id && !isCopyState) { disabled = true; } From a50f003c719474ade61d94778c34f38309a26ceb Mon Sep 17 00:00:00 2001 From: Kurund Jalmi Date: Wed, 29 Nov 2023 00:34:46 +0000 Subject: [PATCH 16/16] more fixes to allow editing during copy action --- src/containers/Template/Form/Template.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/containers/Template/Form/Template.tsx b/src/containers/Template/Form/Template.tsx index e28c1f4cb..695be6525 100644 --- a/src/containers/Template/Form/Template.tsx +++ b/src/containers/Template/Form/Template.tsx @@ -597,7 +597,7 @@ const Template = ({ variant: 'outlined', label: t('Attachment Type'), }, - disabled: !!(defaultAttribute.isHsm && params.id), + disabled: isEditing, helperText: warning, onChange: (event: any) => { const val = event || ''; @@ -613,7 +613,7 @@ const Template = ({ type: 'text', placeholder: t('Attachment URL'), validate: () => isUrlValid, - disabled: !!(defaultAttribute.isHsm && params.id), + disabled: isEditing, helperText: t( 'Please provide a sample attachment for approval purpose. You may send a similar but different attachment when sending the HSM to users.' ), @@ -652,7 +652,7 @@ const Template = ({ variant: 'outlined', label: `${t('Language')}*`, }, - disabled: !!(defaultAttribute.isHsm && params.id), + disabled: isEditing, onChange: getLanguageId, } : { @@ -668,7 +668,7 @@ const Template = ({ component: Input, name: 'label', placeholder: `${t('Title')}*`, - disabled: !!(defaultAttribute.isHsm && params.id), + disabled: isEditing, helperText: defaultAttribute.isHsm ? t('Define what use case does this template serve eg. OTP, optin, activity preference') : null, @@ -683,7 +683,7 @@ const Template = ({ rows: 5, convertToWhatsApp: true, textArea: true, - disabled: !!(defaultAttribute.isHsm && params.id), + disabled: isEditing, helperText: defaultAttribute.isHsm ? '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, @@ -711,7 +711,7 @@ const Template = ({ component: Checkbox, title: Add buttons, name: 'isAddButtonChecked', - disabled: !!(defaultAttribute.isHsm && params.id), + disabled: !!(defaultAttribute.isHsm && params.id && !isCopyState), handleChange: (value: boolean) => setIsAddButtonChecked(value), }, { @@ -719,7 +719,7 @@ const Template = ({ isAddButtonChecked, templateType, inputFields: templateButtons, - disabled: !!params.id, + disabled: isEditing, onAddClick: addTemplateButtons, onRemoveClick: removeTemplateButtons, onInputChange: handeInputChange, @@ -732,7 +732,7 @@ const Template = ({ name: 'tagId', options: tag ? tag.tags : [], optionLabel: 'label', - disabled: false, + disabled: isEditing, hasCreateOption: true, multiple: false, onChange: (value: any) => {