233 lines
7.0 KiB
JavaScript
233 lines
7.0 KiB
JavaScript
// eveai_chat_client/static/assets/js/composables/useTranslation.js
|
|
|
|
import { ref, computed, onMounted } from 'vue';
|
|
|
|
/**
|
|
* Vue 3 Composable for translation management
|
|
* Provides direct backend API communication for translations
|
|
*/
|
|
export function useTranslation() {
|
|
const isTranslationReady = ref(false);
|
|
const currentLanguage = ref('nl');
|
|
const isTranslating = ref(false);
|
|
const lastError = ref(null);
|
|
|
|
// Check if translation system is available
|
|
const checkTranslationReady = () => {
|
|
// Translation is altijd ready omdat we de backend API gebruiken
|
|
// Controleer alleen of we in een browser environment zijn
|
|
if (typeof window !== 'undefined' && typeof fetch !== 'undefined') {
|
|
isTranslationReady.value = true;
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
onMounted(() => {
|
|
// Eenvoudige check - geen retry mechanism nodig
|
|
checkTranslationReady();
|
|
});
|
|
|
|
/**
|
|
* Translate text to target language
|
|
* @param {string} text - Text to translate
|
|
* @param {string} targetLang - Target language code
|
|
* @param {string|null} sourceLang - Source language code (optional)
|
|
* @param {string|null} context - Translation context (optional)
|
|
* @param {string} apiPrefix - API prefix for tenant routing
|
|
* @returns {Promise<object>} Translation result
|
|
*/
|
|
const translate = async (text, targetLang, sourceLang = null, context = null, apiPrefix = '') => {
|
|
if (!text || !text.trim()) {
|
|
const error = new Error('No text provided for translation');
|
|
lastError.value = error;
|
|
throw error;
|
|
}
|
|
|
|
isTranslating.value = true;
|
|
lastError.value = null;
|
|
|
|
try {
|
|
// Bepaal de juiste API URL
|
|
const baseUrl = apiPrefix || window.chatConfig?.apiPrefix || '';
|
|
const apiUrl = `${baseUrl}/api/translate`;
|
|
|
|
// Maak de request payload
|
|
const payload = {
|
|
text: text,
|
|
target_lang: targetLang
|
|
};
|
|
|
|
// Voeg optionele parameters toe
|
|
if (sourceLang) payload.source_lang = sourceLang;
|
|
if (context) payload.context = context;
|
|
|
|
// Maak de HTTP request
|
|
const response = await fetch(apiUrl, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
credentials: 'same-origin', // Voor sessie cookies
|
|
body: JSON.stringify(payload)
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const result = await response.json();
|
|
|
|
// Update current language if translation was successful
|
|
if (result.success) {
|
|
currentLanguage.value = targetLang;
|
|
}
|
|
|
|
return result;
|
|
} catch (error) {
|
|
console.error('Translation error in composable:', error);
|
|
lastError.value = error;
|
|
throw error;
|
|
} finally {
|
|
isTranslating.value = false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Translate text with automatic error handling and loading state
|
|
* @param {string} text - Text to translate
|
|
* @param {string} targetLang - Target language code
|
|
* @param {Object} options - Translation options
|
|
* @returns {Promise<string|null>} Translated text or null on error
|
|
*/
|
|
const translateSafe = async (text, targetLang, options = {}) => {
|
|
const {
|
|
sourceLang = null,
|
|
context = null,
|
|
apiPrefix = '',
|
|
fallbackText = text
|
|
} = options;
|
|
|
|
try {
|
|
const result = await translate(text, targetLang, sourceLang, context, apiPrefix);
|
|
return result.success ? result.translated_text : fallbackText;
|
|
} catch (error) {
|
|
console.warn('Safe translation failed, using fallback:', error.message);
|
|
return fallbackText;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Batch translate multiple texts
|
|
* @param {Array<string>} texts - Array of texts to translate
|
|
* @param {string} targetLang - Target language code
|
|
* @param {Object} options - Translation options
|
|
* @returns {Promise<Array<string>>} Array of translated texts
|
|
*/
|
|
const translateBatch = async (texts, targetLang, options = {}) => {
|
|
const results = await Promise.allSettled(
|
|
texts.map(text => translateSafe(text, targetLang, options))
|
|
);
|
|
|
|
return results.map((result, index) =>
|
|
result.status === 'fulfilled' ? result.value : texts[index]
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Get current language from chatConfig or fallback
|
|
*/
|
|
const getCurrentLanguage = () => {
|
|
return window.chatConfig?.language || currentLanguage.value || 'nl';
|
|
};
|
|
|
|
/**
|
|
* Get API prefix from chatConfig or fallback
|
|
*/
|
|
const getApiPrefix = () => {
|
|
return window.chatConfig?.apiPrefix || '';
|
|
};
|
|
|
|
return {
|
|
// State
|
|
isTranslationReady,
|
|
currentLanguage: computed(() => getCurrentLanguage()),
|
|
isTranslating,
|
|
lastError,
|
|
|
|
// Methods
|
|
translate,
|
|
translateSafe,
|
|
translateBatch,
|
|
|
|
// Utilities
|
|
getCurrentLanguage,
|
|
getApiPrefix
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Simplified composable for basic translation needs
|
|
* Use this when you only need simple text translation
|
|
*/
|
|
export function useTranslationClient() {
|
|
const { translate, translateSafe, isTranslationReady, isTranslating, lastError } = useTranslation();
|
|
|
|
return {
|
|
translate,
|
|
translateSafe,
|
|
isTranslationReady,
|
|
isTranslating,
|
|
lastError
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Composable for reactive text translation
|
|
* Automatically translates text when language changes
|
|
*/
|
|
export function useReactiveTranslation(text, options = {}) {
|
|
const { translateSafe, currentLanguage } = useTranslation();
|
|
const translatedText = ref(text);
|
|
const isLoading = ref(false);
|
|
|
|
const {
|
|
context = null,
|
|
sourceLang = null,
|
|
autoTranslate = true
|
|
} = options;
|
|
|
|
// Watch for language changes and auto-translate
|
|
if (autoTranslate) {
|
|
// We'll implement this when we have proper reactivity setup
|
|
// For now, provide manual translation method
|
|
}
|
|
|
|
const updateTranslation = async (newLanguage = null) => {
|
|
const targetLang = newLanguage || currentLanguage.value;
|
|
|
|
if (!text || targetLang === sourceLang) {
|
|
translatedText.value = text;
|
|
return;
|
|
}
|
|
|
|
isLoading.value = true;
|
|
try {
|
|
const result = await translateSafe(text, targetLang, {
|
|
sourceLang,
|
|
context,
|
|
apiPrefix: window.chatConfig?.apiPrefix || ''
|
|
});
|
|
translatedText.value = result;
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
};
|
|
|
|
return {
|
|
translatedText,
|
|
isLoading,
|
|
updateTranslation
|
|
};
|
|
} |