Skip to content

Commit

Permalink
Merge pull request #1398 from culturecreates/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
sahalali authored Oct 10, 2024
2 parents aa552d6 + 0a49958 commit 7bbe333
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 21 deletions.
3 changes: 3 additions & 0 deletions src/components/MultilingualInput/MultilingualInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -41,6 +42,7 @@ function MultilingualInput({ children, ...rest }) {
placeholderCollection,
skipChildModification = false,
entityId,
form,
} = rest;
const [currentCalendarData] = useOutletContext();
const { t } = useTranslation();
Expand All @@ -56,6 +58,7 @@ function MultilingualInput({ children, ...rest }) {
fieldData,
dataCyCollection,
placeholderCollection,
form,
});

let labelCollection = {};
Expand Down
16 changes: 10 additions & 6 deletions src/components/MultilingualTextEditor/MultiLingualTextEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});

Expand Down Expand Up @@ -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
Expand All @@ -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) => {
Expand Down
9 changes: 9 additions & 0 deletions src/components/TextEditor/TextEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function TextEditor(props) {
editorLanguage,
descriptionMinimumWordCount,
calendarContentLanguage,
form,
} = props;
let translateTo;

Expand Down Expand Up @@ -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()
Expand Down
34 changes: 24 additions & 10 deletions src/hooks/useChildrenWithLanguageFallback.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const CreateMultiLingualFormItems = ({ children, ...rest }) => {
entityId={entityId}
dataCyCollection={dataCyCollection}
required={required}
form={form}
placeholderCollection={placeholderCollection}>
{formItemList}
</MultilingualInput>
Expand Down
1 change: 1 addition & 0 deletions src/pages/Dashboard/AddEvent/AddEvent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <p><br></p> tags at the end
Expand Down
8 changes: 6 additions & 2 deletions src/utils/languageFallbackStatusCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -28,6 +29,7 @@ export function languageFallbackStatusCreator({
fieldData,
languageFallbacks = {},
isFieldsDirty,
currentActiveDataInFormFields = {},
}) {
let results = {};

Expand All @@ -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));
Expand All @@ -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,
};
}
});
Expand Down
33 changes: 30 additions & 3 deletions src/utils/removeUneditedFallbackValues.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,28 @@
* @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 (!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 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) => {
Expand All @@ -24,7 +37,7 @@ export const filterUneditedFallbackValues = ({ values, activeFallbackFieldsInfo
});

// If no matching fallback key is found, return the original values
if (!requiredFallbackKeyForCurrentField) return values;
if (!requiredFallbackKeyForCurrentField) return emptyValueFilter(additionalFilters, values);

let modifiedValues = {};

Expand All @@ -43,5 +56,19 @@ export const filterUneditedFallbackValues = ({ values, activeFallbackFieldsInfo
}
});

return emptyValueFilter(additionalFilters, modifiedValues);
};

const emptyValueFilter = (additionalFilters, modifiedValues) => {
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) {
delete modifiedValues[key];
}
}
});
}

return modifiedValues;
};

0 comments on commit 7bbe333

Please sign in to comment.