All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.resources.page_editor.app.components.Translation.js Maven / Gradle / Ivy

The newest version!
/**
 * SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
 * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
 */

import ClayButton from '@clayui/button';
import {Option, Picker} from '@clayui/core';
import ClayIcon from '@clayui/icon';
import ClayLabel from '@clayui/label';
import Layout from '@clayui/layout';
import classNames from 'classnames';
import {sub} from 'frontend-js-web';
import PropTypes from 'prop-types';
import React, {useMemo} from 'react';

import {updateLanguageId} from '../actions/index';
import {BACKGROUND_IMAGE_FRAGMENT_ENTRY_PROCESSOR} from '../config/constants/backgroundImageFragmentEntryProcessor';
import {EDITABLE_FRAGMENT_ENTRY_PROCESSOR} from '../config/constants/editableFragmentEntryProcessor';
import {TRANSLATION_STATUS_TYPE} from '../config/constants/translationStatusType';

const getEditableValues = (fragmentEntryLinks) =>
	Object.values(fragmentEntryLinks)
		.filter(
			(fragmentEntryLink) =>
				!fragmentEntryLink.masterLayout &&
				!fragmentEntryLink.removed &&
				fragmentEntryLink.editableValues
		)
		.map((fragmentEntryLink) => [
			...Object.values(
				fragmentEntryLink.editableValues[
					EDITABLE_FRAGMENT_ENTRY_PROCESSOR
				] || {}
			),
			...Object.values(
				fragmentEntryLink.editableValues[
					BACKGROUND_IMAGE_FRAGMENT_ENTRY_PROCESSOR
				] || {}
			),
		])
		.reduce(
			(editableValuesA, editableValuesB) => [
				...editableValuesA,
				...editableValuesB,
			],
			[]
		);

const isTranslated = (editableValue, languageId) => editableValue[languageId];

const getTranslationStatus = ({
	editableValuesLength,
	isDefault,
	translatedValuesLength,
}) => {
	if (isDefault) {
		return TRANSLATION_STATUS_TYPE.default;
	}
	else if (translatedValuesLength === 0) {
		return TRANSLATION_STATUS_TYPE.untranslated;
	}
	else if (translatedValuesLength < editableValuesLength) {
		return TRANSLATION_STATUS_TYPE.translating;
	}
	else if (translatedValuesLength === editableValuesLength) {
		return TRANSLATION_STATUS_TYPE.translated;
	}
};

const TRANSLATION_STATUS_LANGUAGE = {
	[TRANSLATION_STATUS_TYPE.default]: Liferay.Language.get('default'),
	[TRANSLATION_STATUS_TYPE.translated]: Liferay.Language.get('translated'),
	[TRANSLATION_STATUS_TYPE.translating]: Liferay.Language.get('translating'),
	[TRANSLATION_STATUS_TYPE.untranslated]:
		Liferay.Language.get('not-translated'),
};

const TRANSLATION_STATUS_DISPLAY_TYPE = {
	[TRANSLATION_STATUS_TYPE.default]: 'info',
	[TRANSLATION_STATUS_TYPE.translated]: 'success',
	[TRANSLATION_STATUS_TYPE.translating]: 'warning',
	[TRANSLATION_STATUS_TYPE.untranslated]: 'warning',
};

const TranslationItem = ({
	editableValuesLength,
	isDefault,
	languageIcon,
	languageId,
	languageLabel,
	selectedLanguageId,
	translatedValuesLength,
}) => {
	const status = getTranslationStatus({
		editableValuesLength,
		isDefault,
		translatedValuesLength,
	});

	const statusText =
		TRANSLATION_STATUS_TYPE[status] === TRANSLATION_STATUS_TYPE.translating
			? `${TRANSLATION_STATUS_LANGUAGE[status]} ${sub(
					Liferay.Language.get('x-of-x'),
					translatedValuesLength,
					editableValuesLength
				)}`
			: `${TRANSLATION_STATUS_LANGUAGE[status]}`;

	return (
		
			
				{`${sub(
					Liferay.Language.get('x-language-x'),
					languageLabel,
					statusText
				)}`}
			

			
				
					
			

			
				
			
		
	);
};

const Trigger = React.forwardRef(
	({languageIcon, w3cLanguageId, ...otherProps}, ref) => (
		
			
		
	)
);
export default function Translation({
	availableLanguages,
	defaultLanguageId,
	dispatch,
	fragmentEntryLinks,
	languageId,
	showNotTranslated = true,
}) {
	const editableValues = useMemo(
		() => getEditableValues(fragmentEntryLinks),
		[fragmentEntryLinks]
	);
	const languageValues = useMemo(() => {
		const availableLanguagesMut = {...availableLanguages};

		const defaultLanguage = availableLanguages[defaultLanguageId];

		delete availableLanguagesMut[defaultLanguageId];

		return Object.keys({
			[defaultLanguageId]: defaultLanguage,
			...availableLanguagesMut,
		})
			.filter(
				(languageId) =>
					showNotTranslated ||
					!!editableValues.filter(
						(editableValue) =>
							isTranslated(editableValue, languageId) ||
							languageId === defaultLanguageId
					).length
			)
			.map((languageId) => ({
				languageId,
				values: editableValues.filter((editableValue) =>
					isTranslated(editableValue, languageId)
				),
			}));
	}, [
		availableLanguages,
		defaultLanguageId,
		editableValues,
		showNotTranslated,
	]);

	const {languageIcon, w3cLanguageId} = availableLanguages[languageId];

	return (
		 {
				dispatch(
					updateLanguageId({
						languageId: key,
					})
				);
			}}
			selectedKey={languageId}
			w3cLanguageId={w3cLanguageId}
		>
			{(language) => (
				
			)}
		
	);
}

Translation.propTypes = {
	availableLanguages: PropTypes.objectOf(
		PropTypes.shape({
			languageIcon: PropTypes.string.isRequired,
			w3cLanguageId: PropTypes.string.isRequired,
		})
	).isRequired,
	defaultLanguageId: PropTypes.string.isRequired,
	dispatch: PropTypes.func.isRequired,
	fragmentEntryLinks: PropTypes.object.isRequired,
	languageId: PropTypes.string.isRequired,
};




© 2015 - 2025 Weber Informatics LLC | Privacy Policy