From f8a817aa5be635b5246a4974492a13f6016f4dcb Mon Sep 17 00:00:00 2001 From: syam babu Date: Fri, 4 Oct 2024 17:54:55 +0530 Subject: [PATCH 1/5] fix: added additional parameter to filter data conditionally in filterUneditedFallbackValues function. Fixed issue with discription with no content being sent to backend. closes #1380 --- src/components/TextEditor/TextEditor.jsx | 9 +++++++++ src/pages/Dashboard/AddEvent/AddEvent.jsx | 1 + src/utils/removeUneditedFallbackValues.js | 17 ++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/components/TextEditor/TextEditor.jsx b/src/components/TextEditor/TextEditor.jsx index 1c78d17d..4636993a 100644 --- a/src/components/TextEditor/TextEditor.jsx +++ b/src/components/TextEditor/TextEditor.jsx @@ -24,6 +24,7 @@ function TextEditor(props) { editorLanguage, descriptionMinimumWordCount, calendarContentLanguage, + form, } = props; let translateTo; @@ -164,6 +165,14 @@ function TextEditor(props) { } }; + useEffect(() => { + const editorWordCountMap = form.getFieldValue(`editor-wordcount-map`) ?? {}; + form.setFieldValue(`editor-wordcount-map`, { + ...editorWordCountMap, + [editorLanguage]: wordCount > 0 ? true : false, + }); + }, [wordCount]); + useEffect(() => { const filteredCount = currentReactQuillRef?.current?.unprivilegedEditor ?.getText() diff --git a/src/pages/Dashboard/AddEvent/AddEvent.jsx b/src/pages/Dashboard/AddEvent/AddEvent.jsx index 349afe34..7349f4dc 100644 --- a/src/pages/Dashboard/AddEvent/AddEvent.jsx +++ b/src/pages/Dashboard/AddEvent/AddEvent.jsx @@ -529,6 +529,7 @@ function AddEvent() { values: values?.editor, activeFallbackFieldsInfo: fallbackStatus, fieldName: 'editor', + additionalFilters: form.getFieldValue('editor-wordcount-map'), }); // Use a regular expression to remove


tags at the end diff --git a/src/utils/removeUneditedFallbackValues.js b/src/utils/removeUneditedFallbackValues.js index 004c4ec4..8c4b7c05 100644 --- a/src/utils/removeUneditedFallbackValues.js +++ b/src/utils/removeUneditedFallbackValues.js @@ -5,11 +5,17 @@ * @param {Object} params.values - The current set of values that need to be filtered. * @param {Object} [params.activeFallbackFieldsInfo={}] - An object containing fallback status information for fields, where keys represent specific field names and values contain details like `tagDisplayStatus` and `fallbackLiteralValue`. * @param {string} params.fieldName - The name of the field that needs to be matched against the fallback fields info. + * @param {Object} params.additionalFilters - Object map that correspond to each language key in data and value corresponding if the value is to be included in the payload or not. * * @returns {Object} - A modified object with filtered values based on the fallback logic. */ -export const filterUneditedFallbackValues = ({ values, activeFallbackFieldsInfo = {}, fieldName }) => { +export const filterUneditedFallbackValues = ({ + values, + activeFallbackFieldsInfo = {}, + fieldName, + additionalFilters, +}) => { let requiredFallbackKeyForCurrentField; // If activeFallbackFieldsInfo is empty, return the original values @@ -43,5 +49,14 @@ export const filterUneditedFallbackValues = ({ values, activeFallbackFieldsInfo } }); + if (additionalFilters) { + Object.keys(additionalFilters).forEach((key) => { + if (Object.prototype.hasOwnProperty.call(modifiedValues, key)) { + if (additionalFilters[key] === false) { + delete modifiedValues[key]; + } + } + }); + } return modifiedValues; }; From 230526b4d9deebd7c8f414345ecec7908cbc7da7 Mon Sep 17 00:00:00 2001 From: syam babu Date: Mon, 7 Oct 2024 13:08:20 +0530 Subject: [PATCH 2/5] fix: seperated empty value filtering function for payload --- src/utils/removeUneditedFallbackValues.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/utils/removeUneditedFallbackValues.js b/src/utils/removeUneditedFallbackValues.js index 8c4b7c05..e6520afd 100644 --- a/src/utils/removeUneditedFallbackValues.js +++ b/src/utils/removeUneditedFallbackValues.js @@ -19,7 +19,7 @@ export const filterUneditedFallbackValues = ({ let requiredFallbackKeyForCurrentField; // If activeFallbackFieldsInfo is empty, return the original values - if (!(Object.keys(activeFallbackFieldsInfo).length > 0)) return values; + if (!(Object.keys(activeFallbackFieldsInfo).length > 0)) return emptyValueFilter(additionalFilters, values); // Determine the required fallback key for the current field Object.keys(activeFallbackFieldsInfo).forEach((key) => { @@ -30,7 +30,7 @@ export const filterUneditedFallbackValues = ({ }); // If no matching fallback key is found, return the original values - if (!requiredFallbackKeyForCurrentField) return values; + if (!requiredFallbackKeyForCurrentField) return emptyValueFilter(additionalFilters, values); let modifiedValues = {}; @@ -49,6 +49,10 @@ export const filterUneditedFallbackValues = ({ } }); + return emptyValueFilter(additionalFilters, modifiedValues); +}; + +const emptyValueFilter = (additionalFilters, modifiedValues) => { if (additionalFilters) { Object.keys(additionalFilters).forEach((key) => { if (Object.prototype.hasOwnProperty.call(modifiedValues, key)) { @@ -58,5 +62,6 @@ export const filterUneditedFallbackValues = ({ } }); } + return modifiedValues; }; From 94c343e73550f66309a76d6cc3d3bf9885e5c0db Mon Sep 17 00:00:00 2001 From: syam babu Date: Wed, 9 Oct 2024 11:24:58 +0530 Subject: [PATCH 3/5] fix: fixed issue error throwing when creating event as draft without description --- src/utils/removeUneditedFallbackValues.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/removeUneditedFallbackValues.js b/src/utils/removeUneditedFallbackValues.js index e6520afd..68e1a94e 100644 --- a/src/utils/removeUneditedFallbackValues.js +++ b/src/utils/removeUneditedFallbackValues.js @@ -53,7 +53,7 @@ export const filterUneditedFallbackValues = ({ }; const emptyValueFilter = (additionalFilters, modifiedValues) => { - if (additionalFilters) { + if (additionalFilters && Object.values(additionalFilters).some((value) => value === true)) { Object.keys(additionalFilters).forEach((key) => { if (Object.prototype.hasOwnProperty.call(modifiedValues, key)) { if (additionalFilters[key] === false) { From 0b3337ab3cb6961536cbb71e09635604c80ae133 Mon Sep 17 00:00:00 2001 From: syam babu Date: Wed, 9 Oct 2024 15:59:27 +0530 Subject: [PATCH 4/5] fix: fixed issue with faulty language fallback getting added in payload during form submission. closes #1390 --- .../MultilingualInput/MultilingualInput.jsx | 3 ++ .../MultiLingualTextEditor.jsx | 16 +++++---- src/hooks/useChildrenWithLanguageFallback.js | 34 +++++++++++++------ .../CreateMultiLingualFormItems.jsx | 1 + src/utils/languageFallbackStatusCreator.js | 8 +++-- 5 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/components/MultilingualInput/MultilingualInput.jsx b/src/components/MultilingualInput/MultilingualInput.jsx index a8c31b3a..d990680c 100644 --- a/src/components/MultilingualInput/MultilingualInput.jsx +++ b/src/components/MultilingualInput/MultilingualInput.jsx @@ -26,6 +26,7 @@ import { ReactComponent as MoveRightExtra } from '../../assets/icons/Right.svg'; * @param {Object} props.placeholderCollection - An object containing the placeholder attribute for each user interactable element eg. textarea. maintains the order of formItems. * @param {string} props.entityId - The entity id. * @param {Boolean} props.skipChildModification - A boolean to skip the modification of children. Default is false. Used as a prop for multilingual text editor. + * @param {Object} params.form - Form instance. Not relevent if skipChildModification is true. * * @returns {React.Element} The rendered form item components. */ @@ -41,6 +42,7 @@ function MultilingualInput({ children, ...rest }) { placeholderCollection, skipChildModification = false, entityId, + form, } = rest; const [currentCalendarData] = useOutletContext(); const { t } = useTranslation(); @@ -56,6 +58,7 @@ function MultilingualInput({ children, ...rest }) { fieldData, dataCyCollection, placeholderCollection, + form, }); let labelCollection = {}; diff --git a/src/components/MultilingualTextEditor/MultiLingualTextEditor.jsx b/src/components/MultilingualTextEditor/MultiLingualTextEditor.jsx index 2cc3c02b..4b764bac 100644 --- a/src/components/MultilingualTextEditor/MultiLingualTextEditor.jsx +++ b/src/components/MultilingualTextEditor/MultiLingualTextEditor.jsx @@ -40,10 +40,11 @@ function MultiLingualTextEditor(props) { }, {}), ); + let combinedName = calendarContentLanguage.map((language) => `${name}` + contentLanguageKeyMap[language]).join('-'); let isFieldsDirty = {}; // to keep track of dirty fields calendarContentLanguage.forEach((language) => { const lanKey = contentLanguageKeyMap[language]; - const fieldName = name.concat([lanKey]); + const fieldName = [`${name}`, lanKey]; isFieldsDirty[lanKey] = form.isFieldTouched(fieldName); }); @@ -126,11 +127,18 @@ function MultiLingualTextEditor(props) { useEffect(() => { if (!currentCalendarData) return; + const currentActiveDataInFormFields = {}; + calendarContentLanguage.forEach((language) => { + const languageKey = contentLanguageKeyMap[language]; + currentActiveDataInFormFields[languageKey] = form.getFieldValue([`${name}`, languageKey]); + }); + const status = languageFallbackStatusCreator({ calendarContentLanguage, fieldData: data, languageFallbacks: currentCalendarData.languageFallbacks, isFieldsDirty, + currentActiveDataInFormFields, }); // Only update fallbackStatus if it has actually changed @@ -154,13 +162,9 @@ function MultiLingualTextEditor(props) { }, [fallbackStatus]); useEffect(() => { - const combinedName = calendarContentLanguage - .map((language) => `${name}` + contentLanguageKeyMap[language]) - .join('-'); - const modifiedActiveFallbackFieldsInfo = { - [combinedName]: fallbackStatus, ...activeFallbackFieldsInfo, + [combinedName]: fallbackStatus, }; const fallbackActiveFlag = calendarContentLanguage.find((language) => { diff --git a/src/hooks/useChildrenWithLanguageFallback.js b/src/hooks/useChildrenWithLanguageFallback.js index f4e1d5c1..78fc9f59 100644 --- a/src/hooks/useChildrenWithLanguageFallback.js +++ b/src/hooks/useChildrenWithLanguageFallback.js @@ -16,32 +16,55 @@ import { languageFallbackStatusCreator } from '../utils/languageFallbackStatusCr * @param {Object} params.fieldData - Collection of data for the field of each content languages. * @param {string[]} params.placeholderCollection - Collection of placeholder texts for each inner child. * @param {string[]} params.dataCyCollection - Collection of data-cy attributes for each inner child. + * @param {Object} params.form - Form instance * * @returns {Object} The fallback status and modified children components. */ function useChildrenWithLanguageFallback({ children, - isFieldsDirty, + isFieldsDirty = {}, currentCalendarData, calendarContentLanguage, fieldData, placeholderCollection, dataCyCollection, + form, }) { const dispatch = useDispatch(); const activeFallbackFieldsInfo = useSelector(getActiveFallbackFieldsInfo); const [fallbackStatus, setFallbackStatus] = useState(null); + let combinedName = children + ?.map((child) => { + const name = child?.props?.name; + if (!name) return ''; + if (Array.isArray(name)) return child?.props?.name.join(''); + else return name; + }) + .join('-'); useEffect(() => { if (!currentCalendarData) return; + const currentActiveDataInFormFields = {}; + + children?.map((child) => { + const name = child?.props?.name; + if (Array.isArray(name)) { + const langKey = name?.length > 1 && name[1]; + if (langKey) { + currentActiveDataInFormFields[langKey] = form.getFieldValue(name); + } + } + }); + const status = languageFallbackStatusCreator({ calendarContentLanguage, fieldData, languageFallbacks: currentCalendarData.languageFallbacks, isFieldsDirty, + currentActiveDataInFormFields, }); // Only update fallbackStatus if it has actually changed @@ -51,15 +74,6 @@ function useChildrenWithLanguageFallback({ }, [children, isFieldsDirty]); useEffect(() => { - const combinedName = children - ?.map((child) => { - const name = child?.props?.name; - if (!name) return ''; - if (Array.isArray(name)) return child?.props?.name.join(''); - else return name; - }) - .join('-'); - const modifiedActiveFallbackFieldsInfo = { ...activeFallbackFieldsInfo, [combinedName]: fallbackStatus, diff --git a/src/layout/CreateMultiLingualFormItems/CreateMultiLingualFormItems.jsx b/src/layout/CreateMultiLingualFormItems/CreateMultiLingualFormItems.jsx index 47eaa750..04deb573 100644 --- a/src/layout/CreateMultiLingualFormItems/CreateMultiLingualFormItems.jsx +++ b/src/layout/CreateMultiLingualFormItems/CreateMultiLingualFormItems.jsx @@ -83,6 +83,7 @@ const CreateMultiLingualFormItems = ({ children, ...rest }) => { entityId={entityId} dataCyCollection={dataCyCollection} required={required} + form={form} placeholderCollection={placeholderCollection}> {formItemList} diff --git a/src/utils/languageFallbackStatusCreator.js b/src/utils/languageFallbackStatusCreator.js index f31ed55b..611e7868 100644 --- a/src/utils/languageFallbackStatusCreator.js +++ b/src/utils/languageFallbackStatusCreator.js @@ -8,6 +8,7 @@ import { contentLanguageKeyMap } from '../constants/contentLanguage'; * @param {Object} params.fieldData - Collection of data for the field of each content languages. * @param {Object} [params.languageFallbacks={}] - Object containing language fallbacks. * @param {Object} params.isFieldsDirty - Object indicating which form fields are dirty. + * @param {Object} params.currentActiveDataInFormFields - The current active data in the form fields. Different from fieldData as fielddata only include data from api response. No realtime update. * * @returns {Object} An object containing the fallback status for each input item. * @@ -28,6 +29,7 @@ export function languageFallbackStatusCreator({ fieldData, languageFallbacks = {}, isFieldsDirty, + currentActiveDataInFormFields = {}, }) { let results = {}; @@ -36,7 +38,7 @@ export function languageFallbackStatusCreator({ calendarContentLanguage.forEach((language) => { const languageKey = contentLanguageKeyMap[language]; - const flag = !Object.hasOwnProperty.call(fieldData, languageKey); + let flag = !Object.hasOwnProperty.call(fieldData, languageKey); if (flag) { const fallbackInfo = languageFallbacks[languageKey]?.find((key) => Object.hasOwnProperty.call(fieldData, key)); @@ -49,7 +51,9 @@ export function languageFallbackStatusCreator({ results[languageKey] = { tagDisplayStatus: !isFieldsDirty[languageKey] ? true : false, fallbackLiteralKey: fallbackErrorHandled?.key, - fallbackLiteralValue: fallbackErrorHandled?.value, + fallbackLiteralValue: isFieldsDirty[languageKey] + ? currentActiveDataInFormFields[languageKey] || '' + : fallbackErrorHandled?.value, }; } }); From 59c663f8dfdaf58d7e535aa8d2e2a36cc4ecdd35 Mon Sep 17 00:00:00 2001 From: syam babu Date: Wed, 9 Oct 2024 19:27:49 +0530 Subject: [PATCH 5/5] fix: filtered empty strings from fields values in payload for event --- src/utils/removeUneditedFallbackValues.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/utils/removeUneditedFallbackValues.js b/src/utils/removeUneditedFallbackValues.js index 68e1a94e..6291ede4 100644 --- a/src/utils/removeUneditedFallbackValues.js +++ b/src/utils/removeUneditedFallbackValues.js @@ -18,6 +18,13 @@ export const filterUneditedFallbackValues = ({ }) => { let requiredFallbackKeyForCurrentField; + if (!additionalFilters && values) { + additionalFilters = Object.keys(values).reduce((filters, key) => { + filters[key] = values[key] !== ''; + return filters; + }, {}); + } + // If activeFallbackFieldsInfo is empty, return the original values if (!(Object.keys(activeFallbackFieldsInfo).length > 0)) return emptyValueFilter(additionalFilters, values);