From 20588533d3eef156c364bbedd6d6eb963c829741 Mon Sep 17 00:00:00 2001 From: duckietm Date: Fri, 22 May 2026 11:47:26 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=86=99=20Added=20translation=20to=20the?= =?UTF-8?q?=20Catalog=20Text?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../catalog/CatalogAdminContext.tsx | 5 +- .../views/admin/CatalogAdminPageEditView.tsx | 105 +++++++++++++++++- src/hooks/translation/useTranslation.ts | 36 +----- 3 files changed, 109 insertions(+), 37 deletions(-) diff --git a/src/components/catalog/CatalogAdminContext.tsx b/src/components/catalog/CatalogAdminContext.tsx index 45aecb6..a0d70fb 100644 --- a/src/components/catalog/CatalogAdminContext.tsx +++ b/src/components/catalog/CatalogAdminContext.tsx @@ -90,7 +90,6 @@ export const CatalogAdminProvider: FC<{ children: ReactNode }> = ({ children }) const pendingActionRef = useRef(null); const { simpleAlert = null } = useNotification(); - // Keyboard shortcuts: Esc to close edit panels useEffect(() => { if(!adminMode) return; @@ -178,11 +177,13 @@ export const CatalogAdminProvider: FC<{ children: ReactNode }> = ({ children }) setLoading(true); setLastError(null); pendingActionRef.current = 'savePage'; + SendMessageComposer(new CatalogAdminSavePageComposer( data.pageId || 0, data.caption, data.captionSave, data.pageLayout, data.iconImage, data.minRank, data.visible === '1', data.enabled === '1', data.orderNum, data.parentId, - data.pageHeadline || '', data.pageTeaser || '', data.pageTextDetails || '', currentType, data.catalogMode + data.pageHeadline || '', data.pageTeaser || '', data.pageTextDetails || '', currentType, data.catalogMode, + data.pageText1 || '' )); }, [ currentType ]); diff --git a/src/components/catalog/views/admin/CatalogAdminPageEditView.tsx b/src/components/catalog/views/admin/CatalogAdminPageEditView.tsx index b6cee3a..b85393a 100644 --- a/src/components/catalog/views/admin/CatalogAdminPageEditView.tsx +++ b/src/components/catalog/views/admin/CatalogAdminPageEditView.tsx @@ -1,7 +1,7 @@ import { FC, useEffect, useState } from 'react'; -import { FaSave, FaSpinner, FaTimes, FaTrash } from 'react-icons/fa'; +import { FaLanguage, FaSave, FaSpinner, FaTimes, FaTrash } from 'react-icons/fa'; import { CatalogType, LocalizeText } from '../../../../api'; -import { useCatalogData, useCatalogUiState } from '../../../../hooks'; +import { useCatalogData, useCatalogUiState, useTranslationActions, useTranslationState } from '../../../../hooks'; import { IPageEditData, useCatalogAdmin } from '../../CatalogAdminContext'; const LAYOUT_OPTIONS = [ @@ -40,6 +40,13 @@ export const CatalogAdminPageEditView: FC<{}> = () => const [ enabled, setEnabled ] = useState('1'); const [ orderNum, setOrderNum ] = useState(0); const [ parentId, setParentId ] = useState(-1); + const [ pageText1, setPageText1 ] = useState(''); + const [ showTranslate, setShowTranslate ] = useState(false); + const [ translateTargetLanguage, setTranslateTargetLanguage ] = useState('en'); + const [ isTranslating, setIsTranslating ] = useState(false); + const [ translateError, setTranslateError ] = useState(null); + const { supportedLanguages = [], languagesLoading = false } = useTranslationState(); + const { translateText, ensureSupportedLanguagesLoaded } = useTranslationActions(); const targetNode = editingPageNode ? editingPageNode : editingRootPage @@ -69,6 +76,14 @@ export const CatalogAdminPageEditView: FC<{}> = () => setEnabled('1'); setMinRank(1); setOrderNum(0); + const matchesLoadedPage = currentPage && targetPageId === currentPage.pageId; + const existingText1 = matchesLoadedPage && currentPage.localization + ? currentPage.localization.getText(0) + : ''; + setPageText1(existingText1 || ''); + setShowTranslate(false); + setIsTranslating(false); + setTranslateError(null); const wireParentId = targetNode.parentId; setParentId(typeof wireParentId === 'number' && wireParentId !== -1 ? wireParentId @@ -95,6 +110,7 @@ export const CatalogAdminPageEditView: FC<{}> = () => enabled, orderNum, parentId, + pageText1, }; catalogAdmin.savePage(data); @@ -102,6 +118,47 @@ export const CatalogAdminPageEditView: FC<{}> = () => closeForm(); }; + const openTranslate = () => + { + const next = !showTranslate; + setShowTranslate(next); + setTranslateError(null); + if(next) ensureSupportedLanguagesLoaded(); + }; + + const runTranslate = async () => + { + if(!pageText1.trim().length) + { + setTranslateError('Nothing to translate yet.'); + return; + } + + if(!translateTargetLanguage) + { + setTranslateError('Pick a language first.'); + return; + } + + setIsTranslating(true); + setTranslateError(null); + + try + { + const result = await translateText(pageText1, translateTargetLanguage); + setPageText1(result?.translatedText || pageText1); + setShowTranslate(false); + } + catch(error) + { + setTranslateError((error as Error)?.message || 'Translation failed.'); + } + finally + { + setIsTranslating(false); + } + }; + const handleDelete = async () => { if(!catalogAdmin?.deletePage || isRoot) return; @@ -168,6 +225,50 @@ export const CatalogAdminPageEditView: FC<{}> = () => { LocalizeText('catalog.admin.enabled') } +
+
+ + +
+ { showTranslate && +
+ + + +
} + { translateError && { translateError } } +