- Eerste stap in het opnieuw laten werken van de chat client...
This commit is contained in:
@@ -346,9 +346,9 @@ class TranslationCache(db.Model):
|
|||||||
class PartnerRAGRetriever(db.Model):
|
class PartnerRAGRetriever(db.Model):
|
||||||
__bind_key__ = 'public'
|
__bind_key__ = 'public'
|
||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
{'schema': 'public'},
|
|
||||||
db.PrimaryKeyConstraint('tenant_id', 'retriever_id'),
|
db.PrimaryKeyConstraint('tenant_id', 'retriever_id'),
|
||||||
db.UniqueConstraint('partner_id', 'tenant_id', 'retriever_id')
|
db.UniqueConstraint('partner_id', 'tenant_id', 'retriever_id'),
|
||||||
|
{'schema': 'public'},
|
||||||
)
|
)
|
||||||
|
|
||||||
partner_id = db.Column(db.Integer, db.ForeignKey('public.partner.id'), nullable=False)
|
partner_id = db.Column(db.Integer, db.ForeignKey('public.partner.id'), nullable=False)
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd /Volumes/OWC4M2_1/Development/Josako/EveAI/TBD/docker
|
||||||
source ./docker_env_switch.sh dev
|
source ./docker_env_switch.sh dev
|
||||||
source .env
|
|
||||||
|
|
||||||
dcdown eveai_chat_client nginx
|
dcdown eveai_chat_client nginx
|
||||||
./update_chat_client_statics.sh
|
|
||||||
|
cd ../nginx
|
||||||
|
|
||||||
|
npm run clean
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
cd ../docker
|
||||||
./build_and_push_eveai.sh -b nginx
|
./build_and_push_eveai.sh -b nginx
|
||||||
|
|
||||||
dcup eveai_chat_client nginx
|
dcup eveai_chat_client nginx
|
||||||
|
|||||||
@@ -1,24 +1,8 @@
|
|||||||
// Import all components
|
// Import all components via barrel export
|
||||||
import { TypingIndicator } from './components/TypingIndicator.js';
|
import { TypingIndicator, FormField, DynamicForm, ChatMessage, MessageHistory, ProgressTracker, LanguageSelector, ChatInput } from './components/index.js';
|
||||||
import { FormField } from './components/FormField.js';
|
|
||||||
import { DynamicForm } from './components/DynamicForm.js';
|
|
||||||
import { ChatMessage } from './components/ChatMessage.js';
|
|
||||||
import { MessageHistory } from './components/MessageHistory.js';
|
|
||||||
import { ProgressTracker } from './components/ProgressTracker.js';
|
|
||||||
import { LanguageSelector } from './components/LanguageSelector.js';
|
|
||||||
|
|
||||||
// Maak componenten globaal beschikbaar voordat andere componenten worden geladen
|
|
||||||
window.DynamicForm = DynamicForm;
|
|
||||||
window.FormField = FormField;
|
|
||||||
window.TypingIndicator = TypingIndicator;
|
|
||||||
window.ChatMessage = ChatMessage;
|
|
||||||
window.MessageHistory = MessageHistory;
|
|
||||||
window.ProgressTracker = ProgressTracker;
|
|
||||||
|
|
||||||
// Nu kunnen we ChatInput importeren nadat de benodigde componenten globaal beschikbaar zijn
|
|
||||||
import { ChatInput } from './components/ChatInput.js';
|
|
||||||
|
|
||||||
// Main Chat Application
|
// Main Chat Application
|
||||||
|
// Main Chat Application - geëxporteerd als module
|
||||||
export const ChatApp = {
|
export const ChatApp = {
|
||||||
name: 'ChatApp',
|
name: 'ChatApp',
|
||||||
components: {
|
components: {
|
||||||
@@ -27,6 +11,7 @@ export const ChatApp = {
|
|||||||
DynamicForm,
|
DynamicForm,
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
MessageHistory,
|
MessageHistory,
|
||||||
|
ProgressTracker,
|
||||||
ChatInput
|
ChatInput
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -36,12 +21,18 @@ export const ChatApp = {
|
|||||||
const settings = chatConfig.settings || {};
|
const settings = chatConfig.settings || {};
|
||||||
const initialLanguage = chatConfig.language || 'nl';
|
const initialLanguage = chatConfig.language || 'nl';
|
||||||
const originalExplanation = chatConfig.explanation || '';
|
const originalExplanation = chatConfig.explanation || '';
|
||||||
|
const tenantMake = chatConfig.tenantMake || {};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
// Tenant info
|
||||||
|
tenantName: tenantMake.name || 'EveAI',
|
||||||
|
tenantLogoUrl: tenantMake.logo_url || '',
|
||||||
|
|
||||||
// Taal gerelateerde data
|
// Taal gerelateerde data
|
||||||
currentLanguage: '',
|
currentLanguage: initialLanguage,
|
||||||
supportedLanguageDetails: chatConfig.supportedLanguageDetails || {},
|
supportedLanguageDetails: chatConfig.supportedLanguageDetails || {},
|
||||||
allowedLanguages: chatConfig.allowedLanguages || ['nl', 'en', 'fr', 'de'],
|
allowedLanguages: chatConfig.allowedLanguages || ['nl', 'en', 'fr', 'de'],
|
||||||
|
supportedLanguages: chatConfig.supportedLanguages || [],
|
||||||
originalExplanation: originalExplanation,
|
originalExplanation: originalExplanation,
|
||||||
explanation: chatConfig.explanation || '',
|
explanation: chatConfig.explanation || '',
|
||||||
|
|
||||||
@@ -88,7 +79,7 @@ export const ChatApp = {
|
|||||||
if (typeof marked === 'function') {
|
if (typeof marked === 'function') {
|
||||||
return marked(this.explanation);
|
return marked(this.explanation);
|
||||||
} else if (marked && typeof marked.parse === 'function') {
|
} else if (marked && typeof marked.parse === 'function') {
|
||||||
return marked.parse(this.explanation);
|
return marked.parse(this.explanation.replace(/\[\[(.*?)\]\]/g, '<strong>$1</strong>'));
|
||||||
} else {
|
} else {
|
||||||
console.error('Marked library not properly loaded');
|
console.error('Marked library not properly loaded');
|
||||||
return this.explanation;
|
return this.explanation;
|
||||||
@@ -101,18 +92,64 @@ export const ChatApp = {
|
|||||||
|
|
||||||
hasMessages() {
|
hasMessages() {
|
||||||
return this.allMessages.length > 0;
|
return this.allMessages.length > 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
displayLanguages() {
|
||||||
|
// Filter de ondersteunde talen op basis van de toegestane talen
|
||||||
|
if (!this.supportedLanguages || !this.allowedLanguages) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.supportedLanguages.filter(lang =>
|
||||||
|
this.allowedLanguages.includes(lang.code)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
console.log('🔍 [DEBUG] ChatApp mounted');
|
||||||
|
console.log('🔍 [DEBUG] ChatApp data:', {
|
||||||
|
tenantName: this.tenantName,
|
||||||
|
currentLanguage: this.currentLanguage,
|
||||||
|
allowedLanguages: this.allowedLanguages,
|
||||||
|
conversationId: this.conversationId,
|
||||||
|
userId: this.userId
|
||||||
|
});
|
||||||
|
|
||||||
|
// Log beschikbare componenten
|
||||||
|
console.log('🔍 [DEBUG] Geregistreerde componenten:', {
|
||||||
|
messageHistory: !!this.$options.components.MessageHistory,
|
||||||
|
chatInput: !!this.$options.components.ChatInput
|
||||||
|
});
|
||||||
|
|
||||||
|
// Render de component
|
||||||
|
this.renderComponent();
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] ChatApp mounted');
|
||||||
|
console.log('🔍 [DEBUG] Props en data:', {
|
||||||
|
currentLanguage: this.currentLanguage,
|
||||||
|
allowedLanguages: this.allowedLanguages,
|
||||||
|
tenantName: this.tenantName
|
||||||
|
});
|
||||||
|
|
||||||
this.initializeChat();
|
this.initializeChat();
|
||||||
this.setupEventListeners();
|
this.setupEventListeners();
|
||||||
|
|
||||||
|
// Render de component
|
||||||
|
this.renderComponent();
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
this.cleanup();
|
this.cleanup();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Nieuwe methode om de component direct te renderen
|
||||||
|
renderComponent() {
|
||||||
|
console.log('🔍 [DEBUG] ChatApp.renderComponent() aangeroepen');
|
||||||
|
// Hier kunnen we directe DOM-manipulatie toevoegen indien nodig
|
||||||
|
// Vergelijkbaar met LanguageSelector.renderComponent()
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
// Initialization
|
// Initialization
|
||||||
initializeChat() {
|
initializeChat() {
|
||||||
@@ -574,6 +611,65 @@ export const ChatApp = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
submitForm(formValues) {
|
||||||
|
console.log('🔍 [DEBUG] Formulier verzenden:', formValues);
|
||||||
|
if (!formValues || this.isLoading) return;
|
||||||
|
|
||||||
|
// Markeer formulier als bezig met verzenden
|
||||||
|
this.isSubmittingForm = true;
|
||||||
|
|
||||||
|
// Voeg gebruikersformulier toe aan chat
|
||||||
|
this.addFormMessage(formValues, 'user');
|
||||||
|
|
||||||
|
// Verstuur naar backend
|
||||||
|
this.sendFormToBackend(formValues);
|
||||||
|
|
||||||
|
// Reset input form
|
||||||
|
this.currentInputFormData = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
sendFormToBackend(formValues) {
|
||||||
|
console.log('🔍 [DEBUG] Formulier naar backend versturen', formValues);
|
||||||
|
// Implementatie voor het versturen van formulier data
|
||||||
|
this.isSubmittingForm = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
sendMessageToBackend(message) {
|
||||||
|
console.log('🔍 [DEBUG] Bericht naar backend versturen', message);
|
||||||
|
// Implementatie voor het versturen van berichten
|
||||||
|
},
|
||||||
|
|
||||||
|
addFormMessage(formValues, sender) {
|
||||||
|
console.log('🔍 [DEBUG] Formulier bericht toevoegen:', formValues);
|
||||||
|
// Implementatie voor het toevoegen van een formulier bericht
|
||||||
|
},
|
||||||
|
|
||||||
|
focusChatInput() {
|
||||||
|
// Focus op de chat input als deze beschikbaar is
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// Controleer of $el beschikbaar is
|
||||||
|
if (!this.$el) {
|
||||||
|
console.warn('$el is niet beschikbaar in focusChatInput');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probeer de input te vinden en focus
|
||||||
|
try {
|
||||||
|
const chatInputComponent = this.$el.querySelector('.chat-input-container');
|
||||||
|
if (chatInputComponent) {
|
||||||
|
console.log('🔍 [DEBUG] Focus op chat input');
|
||||||
|
// Probeer een input element te vinden om focus op te zetten
|
||||||
|
const inputElement = chatInputComponent.querySelector('input, textarea');
|
||||||
|
if (inputElement) {
|
||||||
|
inputElement.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Fout bij focussen op chat input:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
removeMessage(messageId) {
|
removeMessage(messageId) {
|
||||||
const index = this.allMessages.findIndex(m => m.id === messageId);
|
const index = this.allMessages.findIndex(m => m.id === messageId);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
@@ -791,14 +887,186 @@ export const ChatApp = {
|
|||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||||
},
|
},
|
||||||
|
|
||||||
focusChatInput() {
|
|
||||||
this.$refs.chatInput?.focusInput();
|
|
||||||
},
|
|
||||||
|
|
||||||
focusSearch() {
|
focusSearch() {
|
||||||
this.$refs.searchInput?.focus();
|
this.$refs.searchInput?.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderComponent() {
|
||||||
|
console.log('🔍 [DEBUG] ChatApp.renderComponent() aangeroepen');
|
||||||
|
console.log('🔍 [DEBUG] window.Vue beschikbaar:', !!window.Vue);
|
||||||
|
if (window.Vue) {
|
||||||
|
console.log('🔍 [DEBUG] window.Vue.createApp beschikbaar:', !!window.Vue.createApp);
|
||||||
|
console.log('🔍 [DEBUG] window.Vue.version:', window.Vue.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We gaan direct de container manipuleren
|
||||||
|
const container = document.querySelector('.chat-container');
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container niet gevonden voor ChatApp (.chat-container)');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] ChatApp container gevonden, inhoud wordt gerenderd');
|
||||||
|
console.log('🔍 [DEBUG] Beschikbare components:', {
|
||||||
|
MessageHistory: !!window.Components?.MessageHistory,
|
||||||
|
ChatInput: !!window.Components?.ChatInput
|
||||||
|
});
|
||||||
|
|
||||||
|
// Basis layout voor de chat app
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="chat-app-container">
|
||||||
|
<!-- Message History - takes available space -->
|
||||||
|
<div id="chat-message-history" class="chat-messages-area"></div>
|
||||||
|
|
||||||
|
<!-- Chat Input - to the bottom -->
|
||||||
|
<div id="chat-input-container" class="chat-input-area"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Nu we de DOM structuur hebben, gaan we de componenten initialiseren
|
||||||
|
const messageHistoryContainer = document.getElementById('chat-message-history');
|
||||||
|
const chatInputContainer = document.getElementById('chat-input-container');
|
||||||
|
|
||||||
|
// Instantieer MessageHistory component met Vue
|
||||||
|
if (messageHistoryContainer) {
|
||||||
|
console.log('🔍 [DEBUG] MessageHistory container gevonden, initialiseren...');
|
||||||
|
try {
|
||||||
|
// Maak props voor de MessageHistory component
|
||||||
|
const messageHistoryProps = {
|
||||||
|
messages: this.allMessages,
|
||||||
|
isTyping: this.isTyping,
|
||||||
|
isSubmittingForm: this.isSubmittingForm,
|
||||||
|
apiPrefix: this.apiPrefix,
|
||||||
|
autoScroll: true
|
||||||
|
};
|
||||||
|
|
||||||
|
// Maak een nieuwe Vue app en registreer alle componenten
|
||||||
|
const messageHistoryApp = window.Vue.createApp(MessageHistory, messageHistoryProps);
|
||||||
|
|
||||||
|
// Registreer benodigde componenten voor MessageHistory
|
||||||
|
messageHistoryApp.component('chat-message', ChatMessage);
|
||||||
|
messageHistoryApp.component('typing-indicator', TypingIndicator);
|
||||||
|
messageHistoryApp.component('progress-tracker', ProgressTracker);
|
||||||
|
messageHistoryApp.component('dynamic-form', DynamicForm);
|
||||||
|
|
||||||
|
// Error handler
|
||||||
|
messageHistoryApp.config.errorHandler = (err, vm, info) => {
|
||||||
|
console.error('🚨 [Vue Error in MessageHistory]', err);
|
||||||
|
console.error('Component:', vm);
|
||||||
|
console.error('Error Info:', info);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Geef events door naar de ChatApp
|
||||||
|
messageHistoryApp.config.globalProperties.$emit = (event, ...args) => {
|
||||||
|
if (event === 'specialist-complete') {
|
||||||
|
this.handleSpecialistComplete(args[0]);
|
||||||
|
} else if (event === 'specialist-error') {
|
||||||
|
this.handleSpecialistError(args[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mount de component en bewaar de referentie - controleer of renderComponent bestaat
|
||||||
|
let messageHistoryInstance = null;
|
||||||
|
if (typeof MessageHistory.renderComponent === 'function') {
|
||||||
|
messageHistoryInstance = MessageHistory.renderComponent(
|
||||||
|
messageHistoryContainer,
|
||||||
|
messageHistoryProps,
|
||||||
|
messageHistoryApp
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Fallback: direct mounten
|
||||||
|
messageHistoryInstance = messageHistoryApp.mount(messageHistoryContainer);
|
||||||
|
console.log('🔍 [DEBUG] MessageHistory direct gemount via app.mount()');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bewaar de instantie voor toekomstige updates
|
||||||
|
this.$refs.messageHistory = messageHistoryInstance;
|
||||||
|
console.log('🔍 [DEBUG] MessageHistory component succesvol geïnitialiseerd');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij initialiseren MessageHistory:', error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('MessageHistory container niet gevonden in de DOM');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instantieer ChatInput component met Vue
|
||||||
|
if (chatInputContainer) {
|
||||||
|
console.log('🔍 [DEBUG] ChatInput container gevonden, initialiseren...');
|
||||||
|
try {
|
||||||
|
// Maak props voor de ChatInput component
|
||||||
|
const chatInputProps = {
|
||||||
|
currentMessage: this.currentMessage,
|
||||||
|
isLoading: this.isLoading,
|
||||||
|
maxLength: this.settings.maxMessageLength,
|
||||||
|
formData: this.currentInputFormData,
|
||||||
|
allowFileUpload: this.settings.allowFileUpload,
|
||||||
|
allowVoiceMessage: this.settings.allowVoiceMessage
|
||||||
|
};
|
||||||
|
|
||||||
|
// Maak een nieuwe Vue app en registreer alle componenten
|
||||||
|
const chatInputApp = window.Vue.createApp(ChatInput, chatInputProps);
|
||||||
|
|
||||||
|
// Registreer benodigde componenten voor ChatInput
|
||||||
|
chatInputApp.component('dynamic-form', DynamicForm);
|
||||||
|
chatInputApp.component('form-field', FormField);
|
||||||
|
|
||||||
|
// Error handler
|
||||||
|
chatInputApp.config.errorHandler = (err, vm, info) => {
|
||||||
|
console.error('🚨 [Vue Error in ChatInput]', err);
|
||||||
|
console.error('Component:', vm);
|
||||||
|
console.error('Error Info:', info);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Geef events door naar de ChatApp
|
||||||
|
chatInputApp.config.globalProperties.$emit = (event, ...args) => {
|
||||||
|
if (event === 'send-message') {
|
||||||
|
this.sendMessage();
|
||||||
|
} else if (event === 'update-message') {
|
||||||
|
this.updateCurrentMessage(args[0]);
|
||||||
|
} else if (event === 'submit-form') {
|
||||||
|
this.submitFormFromInput(args[0]);
|
||||||
|
} else if (event === 'upload-file') {
|
||||||
|
this.handleFileUpload(args[0]);
|
||||||
|
} else if (event === 'record-voice') {
|
||||||
|
this.handleVoiceRecord(args[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mount de component en bewaar de referentie - controleer of renderComponent bestaat
|
||||||
|
let chatInputInstance = null;
|
||||||
|
if (typeof ChatInput.renderComponent === 'function') {
|
||||||
|
console.log('🔍 [DEBUG] ChatInput.renderComponent wordt aangeroepen met chatInputApp:', chatInputApp);
|
||||||
|
console.log('🔍 [DEBUG] chatInputApp.mount type:', typeof chatInputApp.mount);
|
||||||
|
chatInputInstance = ChatInput.renderComponent(
|
||||||
|
chatInputContainer,
|
||||||
|
chatInputProps,
|
||||||
|
chatInputApp
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Fallback: direct mounten
|
||||||
|
console.log('🔍 [DEBUG] ChatInput wordt direct gemount via app.mount()');
|
||||||
|
chatInputInstance = chatInputApp.mount(chatInputContainer);
|
||||||
|
console.log('🔍 [DEBUG] ChatInput direct gemount via app.mount()');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bewaar de instantie voor toekomstige updates
|
||||||
|
this.$refs.chatInput = chatInputInstance;
|
||||||
|
console.log('🔍 [DEBUG] ChatInput component succesvol geïnitialiseerd');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij initialiseren ChatInput:', error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('ChatInput container niet gevonden in de DOM');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] ChatApp succesvol gerenderd met alle componenten');
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Voeg een minimale render functie toe (vergelijkbaar met LanguageSelector)
|
||||||
|
render() {
|
||||||
|
return document.createElement('div');
|
||||||
},
|
},
|
||||||
|
|
||||||
template: `
|
template: `
|
||||||
@@ -835,101 +1103,4 @@ export const ChatApp = {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Zorg ervoor dat alle componenten correct geïnitialiseerd zijn voordat ze worden gebruikt
|
|
||||||
const initializeApp = () => {
|
|
||||||
console.log('Initializing Chat Application');
|
|
||||||
|
|
||||||
// ChatInput wordt pas op dit punt globaal beschikbaar gemaakt
|
|
||||||
// omdat het afhankelijk is van andere componenten
|
|
||||||
window.ChatInput = ChatInput;
|
|
||||||
|
|
||||||
// Get access to the existing Vue app instance
|
|
||||||
if (window.__vueApp) {
|
|
||||||
|
|
||||||
// Register ALL components globally
|
|
||||||
window.__vueApp.component('TypingIndicator', TypingIndicator);
|
|
||||||
window.__vueApp.component('FormField', FormField);
|
|
||||||
window.__vueApp.component('DynamicForm', DynamicForm);
|
|
||||||
window.__vueApp.component('ChatMessage', ChatMessage);
|
|
||||||
window.__vueApp.component('MessageHistory', MessageHistory);
|
|
||||||
window.__vueApp.component('ChatInput', ChatInput);
|
|
||||||
window.__vueApp.component('ProgressTracker', ProgressTracker);
|
|
||||||
// NB: LanguageSelector wordt niet globaal geregistreerd omdat deze apart gemonteerd wordt
|
|
||||||
console.log('All chat components registered with existing Vue instance');
|
|
||||||
|
|
||||||
// Register the ChatApp component
|
|
||||||
window.__vueApp.component('ChatApp', ChatApp);
|
|
||||||
console.log('ChatApp component registered with existing Vue instance');
|
|
||||||
|
|
||||||
// Mount the Vue app
|
|
||||||
window.__vueApp.mount('#app');
|
|
||||||
console.log('Vue app mounted with chat components');
|
|
||||||
|
|
||||||
} else {
|
|
||||||
console.error('No existing Vue instance found on window.__vueApp');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Functie om LanguageSelector toe te voegen aan sidebar
|
|
||||||
const mountLanguageSelector = () => {
|
|
||||||
const container = document.getElementById('language-selector-container');
|
|
||||||
if (container) {
|
|
||||||
// Maak een eenvoudige Vue app die alleen de LanguageSelector component mount
|
|
||||||
const app = Vue.createApp({
|
|
||||||
components: { LanguageSelector },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
currentLanguage: window.chatConfig?.language || 'nl',
|
|
||||||
supportedLanguageDetails: window.chatConfig?.supportedLanguageDetails || {},
|
|
||||||
allowedLanguages: window.chatConfig?.allowedLanguages || ['nl', 'en', 'fr', 'de']
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleLanguageChange(newLanguage) {
|
|
||||||
console.log(`LanguageSelector: Taal gewijzigd naar ${newLanguage}`);
|
|
||||||
|
|
||||||
// Gebruik ALLEEN de custom event benadering
|
|
||||||
const event = new CustomEvent('language-changed', {
|
|
||||||
detail: { language: newLanguage }
|
|
||||||
});
|
|
||||||
document.dispatchEvent(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
template: `
|
|
||||||
<language-selector
|
|
||||||
:initial-language="currentLanguage"
|
|
||||||
:supported-language-details="supportedLanguageDetails"
|
|
||||||
:allowed-languages="allowedLanguages"
|
|
||||||
@language-changed="handleLanguageChange"
|
|
||||||
></language-selector>
|
|
||||||
`
|
|
||||||
});
|
|
||||||
|
|
||||||
app.component('LanguageSelector', LanguageSelector);
|
|
||||||
app.mount('#language-selector-container');
|
|
||||||
console.log('Language selector mounted in sidebar');
|
|
||||||
} else {
|
|
||||||
console.warn('Language selector container not found');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialize app when DOM is ready
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
console.log('DOM content loaded, initializing application...');
|
|
||||||
|
|
||||||
// Eerst de hoofdapplicatie initialiseren
|
|
||||||
initializeApp();
|
|
||||||
|
|
||||||
// Dan de taal selector monteren met een kleine vertraging
|
|
||||||
// om er zeker van te zijn dat de container is aangemaakt
|
|
||||||
setTimeout(() => {
|
|
||||||
try {
|
|
||||||
mountLanguageSelector();
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Fout bij het monteren van de taal selector:', e);
|
|
||||||
}
|
|
||||||
}, 200);
|
|
||||||
});
|
|
||||||
@@ -1,35 +1,89 @@
|
|||||||
// static/js/components/ChatInput.js
|
// static/js/components/ChatInput.js
|
||||||
|
|
||||||
// Importeer de IconManager (als module systeem wordt gebruikt)
|
// Importeer de benodigde componenten
|
||||||
// Anders moet je ervoor zorgen dat MaterialIconManager.js eerder wordt geladen
|
import { DynamicForm } from './DynamicForm.js';
|
||||||
// en iconManager beschikbaar is via window.iconManager
|
import { IconManagerMixin } from '../iconManager.js';
|
||||||
|
|
||||||
// Voeg stylesheet toe voor ChatInput-specifieke stijlen
|
// CSS wordt nu geladen via de main bundle in chat-client.js
|
||||||
const addStylesheet = () => {
|
// We hoeven hier niets dynamisch te laden
|
||||||
if (!document.querySelector('link[href*="chat-input.css"]')) {
|
|
||||||
const link = document.createElement('link');
|
|
||||||
link.rel = 'stylesheet';
|
|
||||||
link.href = '/static/assets/css/chat-input.css';
|
|
||||||
document.head.appendChild(link);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Laad de stylesheet
|
|
||||||
addStylesheet();
|
|
||||||
|
|
||||||
export const ChatInput = {
|
export const ChatInput = {
|
||||||
name: 'ChatInput',
|
name: 'ChatInput',
|
||||||
components: {
|
components: {
|
||||||
'dynamic-form': window.DynamicForm
|
'dynamic-form': DynamicForm
|
||||||
},
|
},
|
||||||
created() {
|
// Static method for direct rendering
|
||||||
// Als module systeem wordt gebruikt:
|
renderComponent(container, props, app) {
|
||||||
// import { iconManager } from './MaterialIconManager.js';
|
console.log('🔍 [DEBUG] ChatInput.renderComponent() aangeroepen');
|
||||||
// Anders gebruiken we window.iconManager als het beschikbaar is:
|
console.log('🔍 [DEBUG] ChatInput container:', container);
|
||||||
if (window.iconManager && this.formData && this.formData.icon) {
|
console.log('🔍 [DEBUG] ChatInput props:', props);
|
||||||
window.iconManager.ensureIconsLoaded({}, [this.formData.icon]);
|
console.log('🔍 [DEBUG] ChatInput app:', app);
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container element niet gevonden voor ChatInput');
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Controleer de globale dependencies
|
||||||
|
console.log('🔍 [DEBUG] Global dependencies check:');
|
||||||
|
console.log('- window.Vue:', typeof window.Vue);
|
||||||
|
if (window.Vue) {
|
||||||
|
console.log('- window.Vue.createApp:', typeof window.Vue.createApp);
|
||||||
|
console.log('- window.Vue.version:', window.Vue.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] ChatInput container gevonden, Vue app aan het initialiseren');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// We controleren het app object
|
||||||
|
if (!app) {
|
||||||
|
console.error('🚨 [ERROR] Geen Vue app object ontvangen');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check of we een correcte Vue app hebben of we moeten er een maken
|
||||||
|
if (typeof app.mount !== 'function') {
|
||||||
|
console.log('🔍 [DEBUG] Ontvangen app heeft geen mount functie, dit is mogelijk een config object');
|
||||||
|
// Controleer of window.Vue beschikbaar is
|
||||||
|
if (!window.Vue || typeof window.Vue.createApp !== 'function') {
|
||||||
|
console.error('🚨 [ERROR] window.Vue.createApp is niet beschikbaar');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maak een nieuwe Vue app met het ChatInput component en de props
|
||||||
|
console.log('🔍 [DEBUG] Nieuwe Vue app aanmaken met ChatInput component');
|
||||||
|
try {
|
||||||
|
app = window.Vue.createApp(ChatInput, props);
|
||||||
|
console.log('🔍 [DEBUG] Nieuwe app aangemaakt:', app);
|
||||||
|
} catch (createError) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij aanmaken Vue app:', createError);
|
||||||
|
// Probeer een alternatieve aanpak zonder importreferenties
|
||||||
|
console.log('🔍 [DEBUG] Alternatieve aanpak proberen...');
|
||||||
|
const componentCopy = JSON.parse(JSON.stringify(ChatInput));
|
||||||
|
app = window.Vue.createApp(componentCopy, props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stel een fallback DOM in voor het geval mounten mislukt
|
||||||
|
container.innerHTML = `<div class="chat-input-loading">Chat input laden...</div>`;
|
||||||
|
|
||||||
|
// Nu kunnen we de app mounten
|
||||||
|
console.log('🔍 [DEBUG] App.mount aanroepen op container');
|
||||||
|
const instance = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] ChatInput component succesvol gemount, instance:', instance);
|
||||||
|
return instance;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij mounten ChatInput component:', error);
|
||||||
|
console.error('Error stack:', error.stack);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Gebruik de IconManagerMixin om automatisch iconen te laden
|
||||||
|
mixins: [IconManagerMixin],
|
||||||
|
created() {
|
||||||
|
// Als er een formData.icon is, wordt deze automatisch geladen via IconManagerMixin
|
||||||
|
// Geen expliciete window.iconManager calls meer nodig
|
||||||
|
|
||||||
// Maak een benoemde handler voor betere cleanup
|
// Maak een benoemde handler voor betere cleanup
|
||||||
this.languageChangeHandler = (event) => {
|
this.languageChangeHandler = (event) => {
|
||||||
if (event.detail && event.detail.language) {
|
if (event.detail && event.detail.language) {
|
||||||
@@ -342,10 +396,7 @@ export const ChatInput = {
|
|||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
<div class="chat-input-container">
|
<div class="chat-input-container">
|
||||||
<!-- Dynamisch toevoegen van Material Symbols Outlined voor iconen -->
|
<!-- Material Icons worden nu globaal geladen in scripts.html -->
|
||||||
<div v-if="formData && formData.icon" class="material-icons-container">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
|
|
||||||
</div>
|
|
||||||
<!-- Dynamisch formulier container -->
|
<!-- Dynamisch formulier container -->
|
||||||
<div v-if="formData" class="dynamic-form-container">
|
<div v-if="formData" class="dynamic-form-container">
|
||||||
<!-- De titel wordt in DynamicForm weergegeven en niet hier om dubbele titels te voorkomen -->
|
<!-- De titel wordt in DynamicForm weergegeven en niet hier om dubbele titels te voorkomen -->
|
||||||
|
|||||||
@@ -1,35 +1,62 @@
|
|||||||
// Voeg stylesheets toe voor formulier en chat berichten weergave
|
// Import benodigde componenten
|
||||||
const addStylesheets = () => {
|
import { DynamicForm } from './DynamicForm.js';
|
||||||
// Formulier stylesheet
|
import { ProgressTracker } from './ProgressTracker.js';
|
||||||
if (!document.querySelector('link[href*="form-message.css"]')) {
|
|
||||||
const formLink = document.createElement('link');
|
|
||||||
formLink.rel = 'stylesheet';
|
|
||||||
formLink.href = '/static/assets/css/form-message.css';
|
|
||||||
document.head.appendChild(formLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chat bericht stylesheet
|
// CSS en Material Icons worden nu geladen via de hoofdbundel en scripts.html
|
||||||
if (!document.querySelector('link[href*="chat-message.css"]')) {
|
// We hoeven hier niets dynamisch te laden
|
||||||
const chatLink = document.createElement('link');
|
|
||||||
chatLink.rel = 'stylesheet';
|
|
||||||
chatLink.href = '/static/assets/css/chat-message.css';
|
|
||||||
document.head.appendChild(chatLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Material Icons font stylesheet
|
|
||||||
if (!document.querySelector('link[href*="Material+Symbols+Outlined"]')) {
|
|
||||||
const iconLink = document.createElement('link');
|
|
||||||
iconLink.rel = 'stylesheet';
|
|
||||||
iconLink.href = 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0';
|
|
||||||
document.head.appendChild(iconLink);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Laad de stylesheets
|
|
||||||
addStylesheets();
|
|
||||||
|
|
||||||
export const ChatMessage = {
|
export const ChatMessage = {
|
||||||
name: 'ChatMessage',
|
name: 'ChatMessage',
|
||||||
|
// Static method for direct rendering
|
||||||
|
renderComponent(container, props, app) {
|
||||||
|
console.log('🔍 [DEBUG] ChatMessage.renderComponent() aangeroepen');
|
||||||
|
console.log('🔍 [DEBUG] ChatMessage container:', container);
|
||||||
|
console.log('🔍 [DEBUG] ChatMessage props:', props);
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container element niet gevonden voor ChatMessage');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] ChatMessage container gevonden, Vue app aan het initialiseren');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// We controleren het app object
|
||||||
|
if (!app) {
|
||||||
|
console.error('🚨 [ERROR] Geen Vue app object ontvangen');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check of we een correcte Vue app hebben of we moeten er een maken
|
||||||
|
if (typeof app.mount !== 'function') {
|
||||||
|
console.log('🔍 [DEBUG] Ontvangen app heeft geen mount functie, dit is mogelijk een config object');
|
||||||
|
// Controleer of window.Vue beschikbaar is
|
||||||
|
if (!window.Vue || typeof window.Vue.createApp !== 'function') {
|
||||||
|
console.error('🚨 [ERROR] window.Vue.createApp is niet beschikbaar');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maak een nieuwe Vue app met het ChatMessage component en de props
|
||||||
|
console.log('🔍 [DEBUG] Nieuwe Vue app aanmaken met ChatMessage component');
|
||||||
|
app = window.Vue.createApp(ChatMessage, props);
|
||||||
|
console.log('🔍 [DEBUG] Nieuwe app aangemaakt:', app);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nu kunnen we de app mounten
|
||||||
|
console.log('🔍 [DEBUG] App.mount aanroepen op container');
|
||||||
|
const instance = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] ChatMessage component succesvol gemount');
|
||||||
|
return instance;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij mounten ChatMessage component:', error);
|
||||||
|
console.error('Error stack:', error.stack);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'dynamic-form': DynamicForm,
|
||||||
|
'progress-tracker': ProgressTracker
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
message: {
|
message: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
export const DynamicForm = {
|
export const DynamicForm = {
|
||||||
name: 'DynamicForm',
|
name: 'DynamicForm',
|
||||||
|
// Static method for direct rendering
|
||||||
|
renderComponent(container, props, app) {
|
||||||
|
console.log('🔍 [DEBUG] DynamicForm.renderComponent() aangeroepen');
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container element niet gevonden voor DynamicForm');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] DynamicForm container gevonden, Vue app aanmaken');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Maak een nieuwe Vue app instantie met dit component
|
||||||
|
const instance = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] DynamicForm component succesvol gemount');
|
||||||
|
return instance;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij mounten DynamicForm component:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
// Zorg ervoor dat het icoon geladen wordt als iconManager beschikbaar is
|
// Zorg ervoor dat het icoon geladen wordt als iconManager beschikbaar is
|
||||||
if (window.iconManager && this.formData && this.formData.icon) {
|
if (window.iconManager && this.formData && this.formData.icon) {
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
export const FormField = {
|
export const FormField = {
|
||||||
name: 'FormField',
|
name: 'FormField',
|
||||||
|
// Static method for direct rendering
|
||||||
|
renderComponent(container, props, app) {
|
||||||
|
console.log('🔍 [DEBUG] FormField.renderComponent() aangeroepen');
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container element niet gevonden voor FormField');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] FormField container gevonden, Vue app aanmaken');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Maak een nieuwe Vue app instantie met dit component
|
||||||
|
const instance = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] FormField component succesvol gemount');
|
||||||
|
return instance;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij mounten FormField component:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
field: {
|
field: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|||||||
@@ -2,6 +2,52 @@
|
|||||||
|
|
||||||
export const FormMessage = {
|
export const FormMessage = {
|
||||||
name: 'FormMessage',
|
name: 'FormMessage',
|
||||||
|
// Static method for direct rendering
|
||||||
|
renderComponent(container, props, app) {
|
||||||
|
console.log('🔍 [DEBUG] FormMessage.renderComponent() aangeroepen');
|
||||||
|
console.log('🔍 [DEBUG] FormMessage container:', container);
|
||||||
|
console.log('🔍 [DEBUG] FormMessage props:', props);
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container element niet gevonden voor FormMessage');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] FormMessage container gevonden, Vue app aan het initialiseren');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// We controleren het app object
|
||||||
|
if (!app) {
|
||||||
|
console.error('🚨 [ERROR] Geen Vue app object ontvangen');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check of we een correcte Vue app hebben of we moeten er een maken
|
||||||
|
if (typeof app.mount !== 'function') {
|
||||||
|
console.log('🔍 [DEBUG] Ontvangen app heeft geen mount functie, dit is mogelijk een config object');
|
||||||
|
// Controleer of window.Vue beschikbaar is
|
||||||
|
if (!window.Vue || typeof window.Vue.createApp !== 'function') {
|
||||||
|
console.error('🚨 [ERROR] window.Vue.createApp is niet beschikbaar');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maak een nieuwe Vue app met het FormMessage component en de props
|
||||||
|
console.log('🔍 [DEBUG] Nieuwe Vue app aanmaken met FormMessage component');
|
||||||
|
app = window.Vue.createApp(FormMessage, props);
|
||||||
|
console.log('🔍 [DEBUG] Nieuwe app aangemaakt:', app);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nu kunnen we de app mounten
|
||||||
|
console.log('🔍 [DEBUG] App.mount aanroepen op container');
|
||||||
|
const instance = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] FormMessage component succesvol gemount');
|
||||||
|
return instance;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij mounten FormMessage component:', error);
|
||||||
|
console.error('Error stack:', error.stack);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
formData: {
|
formData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export const LanguageSelector = {
|
export const LanguageSelector = {
|
||||||
name: 'LanguageSelector',
|
name: 'LanguageSelector',
|
||||||
props: {
|
props: {
|
||||||
@@ -6,6 +5,10 @@ export const LanguageSelector = {
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'nl'
|
default: 'nl'
|
||||||
},
|
},
|
||||||
|
currentLanguage: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
supportedLanguageDetails: {
|
supportedLanguageDetails: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
@@ -13,22 +16,44 @@ export const LanguageSelector = {
|
|||||||
allowedLanguages: {
|
allowedLanguages: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => ['nl', 'en', 'fr', 'de']
|
default: () => ['nl', 'en', 'fr', 'de']
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed: {
|
},
|
||||||
availableLanguages() {
|
data() {
|
||||||
// Maak een array van taalobjecten op basis van de toegestane talen
|
const startLanguage = this.currentLanguage || this.initialLanguage;
|
||||||
// en de ondersteunde taaldetails
|
return {
|
||||||
const languages = [];
|
selectedLanguage: startLanguage,
|
||||||
|
internalCurrentLanguage: startLanguage
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// console.log('🔍 [DEBUG] LanguageSelector mounted');
|
||||||
|
// console.log('🔍 [DEBUG] Props:', {
|
||||||
|
// initialLanguage: this.initialLanguage,
|
||||||
|
// currentLanguage: this.currentLanguage,
|
||||||
|
// supportedLanguageDetails: this.supportedLanguageDetails,
|
||||||
|
// allowedLanguages: this.allowedLanguages
|
||||||
|
// });
|
||||||
|
|
||||||
// Als er geen toegestane talen zijn of de lijst is leeg, gebruik een standaardlijst
|
// Render the component
|
||||||
|
this.renderComponent();
|
||||||
|
|
||||||
|
// Emit initial language
|
||||||
|
this.$emit('language-changed', this.selectedLanguage);
|
||||||
|
|
||||||
|
// DOM event
|
||||||
|
const event = new CustomEvent('vue:language-changed', {
|
||||||
|
detail: { language: this.selectedLanguage }
|
||||||
|
});
|
||||||
|
document.dispatchEvent(event);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getAvailableLanguages() {
|
||||||
|
const languages = [];
|
||||||
const languagesToUse = (this.allowedLanguages && this.allowedLanguages.length > 0)
|
const languagesToUse = (this.allowedLanguages && this.allowedLanguages.length > 0)
|
||||||
? this.allowedLanguages
|
? this.allowedLanguages
|
||||||
: ['nl', 'en', 'fr', 'de'];
|
: ['nl', 'en', 'fr', 'de'];
|
||||||
|
|
||||||
// Loop door alle ondersteunde taaldetails
|
|
||||||
if (this.supportedLanguageDetails && Object.keys(this.supportedLanguageDetails).length > 0) {
|
if (this.supportedLanguageDetails && Object.keys(this.supportedLanguageDetails).length > 0) {
|
||||||
// Vind talen die overeenkomen met toegestane taalcodes
|
|
||||||
for (const [langName, langDetails] of Object.entries(this.supportedLanguageDetails)) {
|
for (const [langName, langDetails] of Object.entries(this.supportedLanguageDetails)) {
|
||||||
const isoCode = langDetails['iso 639-1'];
|
const isoCode = langDetails['iso 639-1'];
|
||||||
if (languagesToUse.includes(isoCode)) {
|
if (languagesToUse.includes(isoCode)) {
|
||||||
@@ -40,7 +65,6 @@ export const LanguageSelector = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback als er geen taaldetails beschikbaar zijn
|
|
||||||
const defaultLanguages = {
|
const defaultLanguages = {
|
||||||
'nl': { name: 'Nederlands', flag: '🇳🇱' },
|
'nl': { name: 'Nederlands', flag: '🇳🇱' },
|
||||||
'en': { name: 'English', flag: '🇬🇧' },
|
'en': { name: 'English', flag: '🇬🇧' },
|
||||||
@@ -52,67 +76,87 @@ export const LanguageSelector = {
|
|||||||
if (defaultLanguages[code]) {
|
if (defaultLanguages[code]) {
|
||||||
languages.push({
|
languages.push({
|
||||||
code: code,
|
code: code,
|
||||||
name: defaultLanguages[code].code,
|
name: defaultLanguages[code].name,
|
||||||
flag: defaultLanguages[code].flag
|
flag: defaultLanguages[code].flag
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('LanguageSelector: availableLanguages computed:', languages);
|
|
||||||
return languages;
|
return languages;
|
||||||
}
|
|
||||||
},
|
},
|
||||||
emits: ['language-changed'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedLanguage: this.initialLanguage,
|
|
||||||
currentLanguage: this.initialLanguage
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
console.log('LanguageSelector mounted with:', {
|
|
||||||
initialLanguage: this.initialLanguage,
|
|
||||||
selectedLanguage: this.selectedLanguage,
|
|
||||||
availableLanguages: this.availableLanguages
|
|
||||||
});
|
|
||||||
|
|
||||||
// Stuur het language-changed event uit met de initiële taal
|
|
||||||
console.log(`LanguageSelector: Emitting language-changed event for initial language ${this.initialLanguage}`);
|
|
||||||
this.$emit('language-changed', this.initialLanguage);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
changeLanguage(languageCode) {
|
changeLanguage(languageCode) {
|
||||||
console.log(`LanguageSelector: changeLanguage called with ${languageCode}, current: ${this.currentLanguage}`);
|
console.log(`LanguageSelector: changeLanguage called with ${languageCode}`);
|
||||||
|
|
||||||
if (this.currentLanguage !== languageCode) {
|
if (this.internalCurrentLanguage !== languageCode) {
|
||||||
console.log(`LanguageSelector: Emitting language-changed event for ${languageCode}`);
|
this.internalCurrentLanguage = languageCode;
|
||||||
this.currentLanguage = languageCode;
|
this.selectedLanguage = languageCode;
|
||||||
|
|
||||||
|
// Vue component emit
|
||||||
this.$emit('language-changed', languageCode);
|
this.$emit('language-changed', languageCode);
|
||||||
} else {
|
|
||||||
console.log(`LanguageSelector: No change needed, already ${languageCode}`);
|
// DOM event
|
||||||
}
|
const event = new CustomEvent('vue:language-changed', {
|
||||||
|
detail: { language: languageCode }
|
||||||
|
});
|
||||||
|
document.dispatchEvent(event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderComponent() {
|
||||||
|
// We gaan direct de container manipuleren
|
||||||
|
const container = document.getElementById('language-selector-container');
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container niet gevonden voor LanguageSelector');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const availableLanguages = this.getAvailableLanguages();
|
||||||
|
// console.log('🔍 [DEBUG] Available languages:', availableLanguages);
|
||||||
|
|
||||||
|
const optionsHtml = availableLanguages.map(lang =>
|
||||||
|
`<option value="${lang.code}" ${lang.code === this.selectedLanguage ? 'selected' : ''}>${lang.flag} ${lang.name}</option>`
|
||||||
|
).join('');
|
||||||
|
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="language-selector">
|
||||||
|
<label for="language-select">Taal / Language:</label>
|
||||||
|
<div class="select-wrapper">
|
||||||
|
<select id="language-select" class="language-select">
|
||||||
|
${optionsHtml}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Add event listener
|
||||||
|
const selectElement = container.querySelector('#language-select');
|
||||||
|
if (selectElement) {
|
||||||
|
selectElement.addEventListener('change', (e) => {
|
||||||
|
this.changeLanguage(e.target.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('🔍 [DEBUG] Component rendered successfully');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Stap 1: Ondersteun zowel template-based rendering als manual rendering
|
||||||
|
// Door beide methoden te ondersteunen, werkt het component in beide scenario's
|
||||||
template: `
|
template: `
|
||||||
<div class="language-selector">
|
<div class="language-selector">
|
||||||
<label for="language-select">Taal / Language:</label>
|
<label for="language-select">Taal / Language:</label>
|
||||||
<div class="select-wrapper">
|
<div class="select-wrapper">
|
||||||
<select
|
<select id="language-select" class="language-select" v-model="selectedLanguage" @change="changeLanguage(selectedLanguage)">
|
||||||
id="language-select"
|
<option v-for="lang in getAvailableLanguages()" :key="lang.code" :value="lang.code">{{ lang.flag }} {{ lang.name }}</option>
|
||||||
v-model="selectedLanguage"
|
|
||||||
@change="changeLanguage(selectedLanguage); currentLanguage = selectedLanguage"
|
|
||||||
class="language-select"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
v-for="lang in availableLanguages"
|
|
||||||
:key="lang.code"
|
|
||||||
:value="lang.code"
|
|
||||||
>
|
|
||||||
{{ lang.flag }} {{ lang.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`,
|
||||||
|
|
||||||
|
// Minimale render functie als fallback
|
||||||
|
render() {
|
||||||
|
return document.createElement('div');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,15 @@
|
|||||||
|
// Import afhankelijke componenten
|
||||||
|
import { ChatMessage } from './ChatMessage.js';
|
||||||
|
import { TypingIndicator } from './TypingIndicator.js';
|
||||||
|
import { ProgressTracker } from './ProgressTracker.js';
|
||||||
|
|
||||||
export const MessageHistory = {
|
export const MessageHistory = {
|
||||||
name: 'MessageHistory',
|
name: 'MessageHistory',
|
||||||
|
components: {
|
||||||
|
'chat-message': ChatMessage,
|
||||||
|
'typing-indicator': TypingIndicator,
|
||||||
|
'progress-tracker': ProgressTracker
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
messages: {
|
messages: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -216,5 +226,27 @@ export const MessageHistory = {
|
|||||||
<typing-indicator v-if="isTyping"></typing-indicator>
|
<typing-indicator v-if="isTyping"></typing-indicator>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`
|
||||||
|
};
|
||||||
|
|
||||||
|
// Statische renderComponent methode voor het MessageHistory object
|
||||||
|
MessageHistory.renderComponent = function(container, props, app) {
|
||||||
|
console.log('🔍 [DEBUG] MessageHistory.renderComponent() aangeroepen als statische methode');
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container element niet gevonden voor MessageHistory');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] MessageHistory container gevonden, Vue app aanmaken');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Maak een nieuwe Vue app instantie met dit component
|
||||||
|
const instance = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] MessageHistory component succesvol gemount');
|
||||||
|
return instance;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij mounten MessageHistory component:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
@@ -309,3 +309,25 @@ export const ProgressTracker = {
|
|||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Voeg de renderComponent toe als statische methode op het ProgressTracker object
|
||||||
|
ProgressTracker.renderComponent = function(container, props, app) {
|
||||||
|
console.log('🔍 [DEBUG] ProgressTracker.renderComponent() aangeroepen');
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container element niet gevonden voor ProgressTracker');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] ProgressTracker container gevonden, Vue app aanmaken');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Maak een nieuwe Vue app instantie met dit component
|
||||||
|
const instance = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] ProgressTracker component succesvol gemount');
|
||||||
|
return instance;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij mounten ProgressTracker component:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,10 +1,46 @@
|
|||||||
export const TypingIndicator = {
|
export const TypingIndicator = {
|
||||||
name: 'TypingIndicator',
|
name: 'TypingIndicator',
|
||||||
|
props: {
|
||||||
|
showText: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: 'Bezig met typen...'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// Andere methoden kunnen hier staan
|
||||||
|
},
|
||||||
template: `
|
template: `
|
||||||
<div class="typing-indicator">
|
<div class="typing-indicator">
|
||||||
<div class="typing-dot"></div>
|
<div class="typing-dot"></div>
|
||||||
<div class="typing-dot"></div>
|
<div class="typing-dot"></div>
|
||||||
<div class="typing-dot"></div>
|
<div class="typing-dot"></div>
|
||||||
|
<div v-if="showText" class="typing-text">{{ text }}</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Voeg statische renderComponent methode toe aan het TypingIndicator object
|
||||||
|
TypingIndicator.renderComponent = function(container, props, app) {
|
||||||
|
console.log('🔍 [DEBUG] TypingIndicator.renderComponent() aangeroepen als statische methode');
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('Container element niet gevonden voor TypingIndicator');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] TypingIndicator container gevonden, Vue app aanmaken');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Maak een nieuwe Vue app instantie met dit component
|
||||||
|
const instance = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] TypingIndicator component succesvol gemount');
|
||||||
|
return instance;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij mounten TypingIndicator component:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
34
eveai_chat_client/static/assets/js/components/index.js
Normal file
34
eveai_chat_client/static/assets/js/components/index.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// Component barrel export file
|
||||||
|
// Dit bestand maakt het eenvoudiger om alle componenten in één keer te importeren
|
||||||
|
|
||||||
|
// Importeer eerst alle componenten lokaal
|
||||||
|
import { TypingIndicator } from './TypingIndicator.js';
|
||||||
|
import { FormField } from './FormField.js';
|
||||||
|
import { DynamicForm } from './DynamicForm.js';
|
||||||
|
import { ChatMessage } from './ChatMessage.js';
|
||||||
|
import { MessageHistory } from './MessageHistory.js';
|
||||||
|
import { ProgressTracker } from './ProgressTracker.js';
|
||||||
|
import { LanguageSelector } from './LanguageSelector.js';
|
||||||
|
import { ChatInput } from './ChatInput.js';
|
||||||
|
|
||||||
|
// Exporteer componenten individueel
|
||||||
|
export { TypingIndicator };
|
||||||
|
export { FormField };
|
||||||
|
export { DynamicForm };
|
||||||
|
export { ChatMessage };
|
||||||
|
export { MessageHistory };
|
||||||
|
export { ProgressTracker };
|
||||||
|
export { LanguageSelector };
|
||||||
|
export { ChatInput };
|
||||||
|
|
||||||
|
// Debug logging voor index.js
|
||||||
|
console.log('🔍 [DEBUG] Components index.js geladen, exporteert:', {
|
||||||
|
TypingIndicator: typeof TypingIndicator,
|
||||||
|
ChatMessage: typeof ChatMessage,
|
||||||
|
MessageHistory: typeof MessageHistory,
|
||||||
|
ChatInput: typeof ChatInput
|
||||||
|
});
|
||||||
|
|
||||||
|
// Nu kunnen componenten op verschillende manieren worden geïmporteerd:
|
||||||
|
// 1. import { FormField, ChatMessage } from './components';
|
||||||
|
// 2. import { ChatInput } from './components/ChatInput.js';
|
||||||
@@ -88,48 +88,43 @@ window.iconManager = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Functie om iconManager toe te voegen aan het DynamicForm component
|
// Export de iconManager functie om te gebruiken in Vue componenten
|
||||||
function initDynamicFormWithIcons() {
|
// Dit vervangt de complexe injectie in het DynamicForm component
|
||||||
if (window.DynamicForm) {
|
export { iconManager as default };
|
||||||
const originalCreated = window.DynamicForm.created || function() {};
|
|
||||||
|
|
||||||
window.DynamicForm.created = function() {
|
// We exporteren iconManager als default, maar houden ook de window.iconManager beschikbaar
|
||||||
// Roep de oorspronkelijke created methode aan als die bestond
|
// voor backwards compatibility met bestaande code
|
||||||
originalCreated.call(this);
|
|
||||||
|
|
||||||
// Laad het icoon als het beschikbaar is
|
// Maak een Vue mixin die iconManager toevoegt aan elk component dat het nodig heeft
|
||||||
|
export const IconManagerMixin = {
|
||||||
|
created() {
|
||||||
|
// Check of er een formData.icon property is
|
||||||
if (this.formData && this.formData.icon) {
|
if (this.formData && this.formData.icon) {
|
||||||
window.iconManager.loadIcon(this.formData.icon);
|
window.iconManager.loadIcon(this.formData.icon);
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
// Voeg watcher toe voor formData.icon
|
// Watch voor formData.icon veranderingen
|
||||||
if (!window.DynamicForm.watch) {
|
watch: {
|
||||||
window.DynamicForm.watch = {};
|
'formData.icon': function(newIcon) {
|
||||||
}
|
|
||||||
|
|
||||||
window.DynamicForm.watch['formData.icon'] = {
|
|
||||||
handler: function(newIcon) {
|
|
||||||
if (newIcon) {
|
if (newIcon) {
|
||||||
window.iconManager.loadIcon(newIcon);
|
window.iconManager.loadIcon(newIcon);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
immediate: true
|
|
||||||
|
// Methode om toe te voegen aan componenten
|
||||||
|
methods: {
|
||||||
|
loadIcon(iconName, options) {
|
||||||
|
window.iconManager.loadIcon(iconName, options);
|
||||||
|
},
|
||||||
|
|
||||||
|
loadIcons(iconNames, options) {
|
||||||
|
window.iconManager.loadIcons(iconNames, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('DynamicForm is uitgebreid met iconManager functionaliteit');
|
// We hoeven niet langer DynamicForm te manipuleren
|
||||||
} else {
|
// omdat Vue componenten nu de IconManagerMixin kunnen gebruiken
|
||||||
console.warn('DynamicForm component is niet beschikbaar. iconManager kan niet worden toegevoegd.');
|
console.log('IconManager en IconManagerMixin zijn beschikbaar voor componenten');
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Probeer het DynamicForm component te initialiseren zodra het document geladen is
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
// Wacht een korte tijd om er zeker van te zijn dat DynamicForm is geladen
|
|
||||||
setTimeout(initDynamicFormWithIcons, 100);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Als DynamicForm al beschikbaar is, initialiseer direct
|
|
||||||
if (window.DynamicForm) {
|
|
||||||
initDynamicFormWithIcons();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
{{ tenant_make.name|default('') }}
|
{{ tenant_make.name|default('') }}
|
||||||
</div>
|
</div>
|
||||||
<div id="language-selector-container"></div>
|
<div id="language-selector-container"></div>
|
||||||
<div class="sidebar-explanation" v-html="compiledExplanation"></div>
|
<div class="sidebar-explanation" id="sidebar-explanation"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right content area - contains the chat client -->
|
<!-- Right content area - contains the chat client -->
|
||||||
@@ -47,44 +47,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="{{url_for('static', filename='dist/chat-client.js')}}"></script>
|
{% include 'scripts.html' %}
|
||||||
<script>
|
|
||||||
// Maak ondersteunde talen beschikbaar voor de client
|
|
||||||
window.config = {
|
|
||||||
supportedLanguages: [
|
|
||||||
{% for lang_code in config.SUPPORTED_LANGUAGES %}
|
|
||||||
{
|
|
||||||
code: "{{ lang_code }}",
|
|
||||||
name: "{{ config.SUPPORTED_LANGUAGE_DETAILS[config.SUPPORTED_LANGUAGES_FULL[loop.index0]]['iso 639-1'] }}",
|
|
||||||
flag: "{{ config.SUPPORTED_LANGUAGE_DETAILS[config.SUPPORTED_LANGUAGES_FULL[loop.index0]]['flag'] }}"
|
|
||||||
}{% if not loop.last %},{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create Vue app and make it available globally
|
|
||||||
window.__vueApp = Vue.createApp({
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
explanation: `{{ customisation.sidebar_markdown|default('') }}`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
compiledExplanation: function() {
|
|
||||||
// Handle different versions of the marked library
|
|
||||||
if (typeof marked === 'function') {
|
|
||||||
return marked(this.explanation);
|
|
||||||
} else if (marked && typeof marked.parse === 'function') {
|
|
||||||
return marked.parse(this.explanation);
|
|
||||||
} else {
|
|
||||||
console.error('Marked library not properly loaded');
|
|
||||||
return this.explanation; // Fallback to raw text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{% block scripts %}{% endblock %}
|
{% block scripts %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -4,10 +4,8 @@
|
|||||||
{% block title %}{{ tenant_make.name|default('EveAI') }} - AI Chat{% endblock %}
|
{% block title %}{{ tenant_make.name|default('EveAI') }} - AI Chat{% endblock %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<!-- Chat specific CSS -->
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='assets/css/chat-components.css') }}">
|
|
||||||
|
|
||||||
<!-- Pass server data to JavaScript -->
|
<!-- Pass server data to JavaScript - vroeg in de head -->
|
||||||
<script>
|
<script>
|
||||||
// Definieer chatConfig voordat componenten worden geladen
|
// Definieer chatConfig voordat componenten worden geladen
|
||||||
window.chatConfig = {
|
window.chatConfig = {
|
||||||
@@ -24,7 +22,11 @@
|
|||||||
apiPrefix: '{{ request.headers.get("X-Forwarded-Prefix", "") }}',
|
apiPrefix: '{{ request.headers.get("X-Forwarded-Prefix", "") }}',
|
||||||
language: '{{ session.magic_link.specialist_args.language|default("nl") }}',
|
language: '{{ session.magic_link.specialist_args.language|default("nl") }}',
|
||||||
supportedLanguageDetails: {{ config.SUPPORTED_LANGUAGE_DETAILS|tojson|safe }},
|
supportedLanguageDetails: {{ config.SUPPORTED_LANGUAGE_DETAILS|tojson|safe }},
|
||||||
allowedLanguages: {{ tenant_make.allowed_languages|tojson|safe }}
|
allowedLanguages: {{ tenant_make.allowed_languages|tojson|safe }},
|
||||||
|
tenantMake: {
|
||||||
|
name: "{{ tenant_make.name|default('EveAI') }}",
|
||||||
|
logo_url: "{{ tenant_make.logo_url|default('') }}"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Debug info om te controleren of chatConfig correct is ingesteld
|
// Debug info om te controleren of chatConfig correct is ingesteld
|
||||||
@@ -33,14 +35,11 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<!-- Gebruik het ChatApp component -->
|
<!-- De chat container is leeg en wordt via JavaScript gevuld -->
|
||||||
<chat-app>
|
<!-- Het ChatApp component wordt via de app-initializer gemount -->
|
||||||
</chat-app>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<!-- Import components and main app -->
|
<!-- Alle componenten worden al geladen via chat-client.js in scripts.html -->
|
||||||
<!-- Alle componenten worden geladen met absolute paden vanaf /static/ -->
|
<!-- Geen extra imports nodig -->
|
||||||
<script type="module" src="{{ url_for('static', filename='assets/js/chat-app.js') }}"></script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
33
eveai_chat_client/templates/scripts.html
Normal file
33
eveai_chat_client/templates/scripts.html
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!-- Material Icons voor icoontjes in de interface -->
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0">
|
||||||
|
|
||||||
|
<!-- Chat client JS - bundled met alle componenten en ES modules -->
|
||||||
|
<script src="{{url_for('static', filename='dist/chat-client.js')}}"></script>
|
||||||
|
<script>
|
||||||
|
// Voeg taalinstellingen toe aan chatConfig indien deze nog niet bestaan
|
||||||
|
if (window.chatConfig) {
|
||||||
|
// Maak supportedLanguages beschikbaar voor de client
|
||||||
|
window.chatConfig.supportedLanguages = [
|
||||||
|
{% for lang_code in config.SUPPORTED_LANGUAGES %}
|
||||||
|
{
|
||||||
|
code: "{{ lang_code }}",
|
||||||
|
name: "{{ config.SUPPORTED_LANGUAGE_DETAILS[config.SUPPORTED_LANGUAGES_FULL[loop.index0]]['iso 639-1'] }}",
|
||||||
|
flag: "{{ config.SUPPORTED_LANGUAGE_DETAILS[config.SUPPORTED_LANGUAGES_FULL[loop.index0]]['flag'] }}"
|
||||||
|
}{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Voeg tenantMake toe aan chatConfig als die nog niet bestaat
|
||||||
|
if (!window.chatConfig.tenantMake) {
|
||||||
|
window.chatConfig.tenantMake = {
|
||||||
|
name: "{{ tenant_make.name|default('EveAI') }}",
|
||||||
|
logo_url: "{{ tenant_make.logo_url|default('') }}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Taalinstellingen toegevoegd aan chatConfig');
|
||||||
|
} else {
|
||||||
|
console.warn('chatConfig is niet gedefinieerd in scripts.html');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
72
frontend_src/js/chat-client.js
Normal file
72
frontend_src/js/chat-client.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// Chat Client JavaScript modules
|
||||||
|
// Modern gebundelde versie met ES modules
|
||||||
|
|
||||||
|
// CSS imports - zorg dat deze bestanden bestaan en correct worden gebundeld door Parcel
|
||||||
|
import '../css/chat-client.css';
|
||||||
|
// CSS imports uit eveai_chat_client
|
||||||
|
import '../../../eveai_chat_client/static/assets/css/chat.css';
|
||||||
|
import '../../../eveai_chat_client/static/assets/css/chat-components.css';
|
||||||
|
import '../../../eveai_chat_client/static/assets/css/chat-input.css';
|
||||||
|
import '../../../eveai_chat_client/static/assets/css/chat-message.css';
|
||||||
|
import '../../../eveai_chat_client/static/assets/css/form.css';
|
||||||
|
import '../../../eveai_chat_client/static/assets/css/form-message.css';
|
||||||
|
import '../../../eveai_chat_client/static/assets/css/language-selector.css';
|
||||||
|
|
||||||
|
// Dependencies
|
||||||
|
import { createApp } from 'vue';
|
||||||
|
import { marked } from 'marked';
|
||||||
|
|
||||||
|
// Maak fundamentele libraries globaal beschikbaar
|
||||||
|
window.Vue = { createApp };
|
||||||
|
window.marked = marked;
|
||||||
|
|
||||||
|
// Support tools
|
||||||
|
import iconManager, { IconManagerMixin } from '../../../eveai_chat_client/static/assets/js/iconManager.js';
|
||||||
|
import '../../../eveai_chat_client/static/assets/js/translation.js';
|
||||||
|
|
||||||
|
// Gebruik barrel export voor componenten
|
||||||
|
import * as Components from '../../../eveai_chat_client/static/assets/js/components/index.js';
|
||||||
|
|
||||||
|
// Maak Components globaal beschikbaar voor debugging
|
||||||
|
window.Components = Components;
|
||||||
|
console.log('Components loaded:', Object.keys(Components));
|
||||||
|
|
||||||
|
// Main chat application - moet als laatste worden geladen
|
||||||
|
import { ChatApp } from '../../../eveai_chat_client/static/assets/js/ChatApp.js';
|
||||||
|
|
||||||
|
// Wacht tot het document volledig is geladen voordat we Vue initialiseren
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
console.log('Initializing Chat Application');
|
||||||
|
|
||||||
|
// Check of #app element bestaat
|
||||||
|
const appElement = document.getElementById('app');
|
||||||
|
if (!appElement) {
|
||||||
|
console.error('DOM element #app not found. Cannot initialize Vue application.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('DOM element #app exists:', appElement);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Maak de Vue applicatie aan
|
||||||
|
const app = createApp(ChatApp);
|
||||||
|
|
||||||
|
// Registreer alle componenten globaal
|
||||||
|
for (const [name, component] of Object.entries(Components)) {
|
||||||
|
app.component(name, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Voeg de IconManagerMixin toe voor alle componenten
|
||||||
|
app.mixin(IconManagerMixin);
|
||||||
|
|
||||||
|
// Mount de applicatie op #app
|
||||||
|
const mountedApp = app.mount('#app');
|
||||||
|
|
||||||
|
// Bewaar een referentie naar de app voor debugging
|
||||||
|
window.__vueApp = app;
|
||||||
|
|
||||||
|
console.log('Vue app mounted successfully');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error initializing Vue application:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
// Chat Client JavaScript modules
|
// CSS imports
|
||||||
// Importeer alle chat client componenten
|
|
||||||
|
|
||||||
import '../css/chat-client.css';
|
import '../css/chat-client.css';
|
||||||
|
|
||||||
import '../../../eveai_chat_client/static/assets/css/chat.css';
|
import '../../../eveai_chat_client/static/assets/css/chat.css';
|
||||||
import '../../../eveai_chat_client/static/assets/css/chat-components.css';
|
import '../../../eveai_chat_client/static/assets/css/chat-components.css';
|
||||||
import '../../../eveai_chat_client/static/assets/css/chat-input.css';
|
import '../../../eveai_chat_client/static/assets/css/chat-input.css';
|
||||||
@@ -11,29 +8,295 @@ import '../../../eveai_chat_client/static/assets/css/form.css';
|
|||||||
import '../../../eveai_chat_client/static/assets/css/form-message.css';
|
import '../../../eveai_chat_client/static/assets/css/form-message.css';
|
||||||
import '../../../eveai_chat_client/static/assets/css/language-selector.css';
|
import '../../../eveai_chat_client/static/assets/css/language-selector.css';
|
||||||
|
|
||||||
import { createApp } from 'vue';
|
// Dependencies
|
||||||
window.Vue = { createApp };
|
import { createApp, version } from 'vue';
|
||||||
|
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
|
import { FormField } from '../../../eveai_chat_client/static/assets/js/components/FormField.js';
|
||||||
|
|
||||||
|
// Vue en andere bibliotheken beschikbaar maken
|
||||||
|
window.Vue = { createApp, version };
|
||||||
window.marked = marked;
|
window.marked = marked;
|
||||||
|
|
||||||
|
// Debug: Check Vue build type
|
||||||
|
console.log('🔍 [DEBUG] Vue object:', window.Vue);
|
||||||
|
console.log('🔍 [DEBUG] Vue.createApp:', typeof window.Vue.createApp);
|
||||||
|
console.log('🔍 [DEBUG] Vue.version:', window.Vue.version);
|
||||||
|
|
||||||
|
// Support tools
|
||||||
// Main chat application
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/chat-app.js';
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/iconManager.js';
|
import '../../../eveai_chat_client/static/assets/js/iconManager.js';
|
||||||
import '../../../eveai_chat_client/static/assets/js/translation.js';
|
import '../../../eveai_chat_client/static/assets/js/translation.js';
|
||||||
|
|
||||||
// Chat components
|
// Gebruik barrel export voor componenten
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/ChatInput.js';
|
import * as Components from '../../../eveai_chat_client/static/assets/js/components/index.js';
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/ChatMessage.js';
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/DynamicForm.js';
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/FormField.js';
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/FormMessage.js';
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/LanguageSelector.js';
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/MaterialIconManager.js';
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/MessageHistory.js';
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/ProgressTracker.js';
|
|
||||||
import '../../../eveai_chat_client/static/assets/js/components/TypingIndicator.js';
|
|
||||||
|
|
||||||
console.log('Chat client modules geladen en gebundeld.');
|
// Maak Components globaal beschikbaar voor debugging
|
||||||
|
window.Components = Components;
|
||||||
|
console.log('Components loaded:', Object.keys(Components));
|
||||||
|
|
||||||
|
// Import specifieke componenten
|
||||||
|
import { LanguageSelector } from '../../../eveai_chat_client/static/assets/js/components/LanguageSelector.js';
|
||||||
|
import { ChatApp } from '../../../eveai_chat_client/static/assets/js/ChatApp.js';
|
||||||
|
|
||||||
|
// Globale Vue error tracking
|
||||||
|
window.addEventListener('error', function(event) {
|
||||||
|
console.error('🚨 [Global Error]', event.error);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wacht tot DOM geladen is
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
console.log('🔍 [DEBUG] DOM content loaded, initializing application...');
|
||||||
|
|
||||||
|
// Controleer of chatConfig is ingesteld
|
||||||
|
if (!window.chatConfig) {
|
||||||
|
console.error('chatConfig is niet beschikbaar');
|
||||||
|
window.chatConfig = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vul de sidebar explanation in
|
||||||
|
fillSidebarExplanation();
|
||||||
|
|
||||||
|
// Initialiseer language selector
|
||||||
|
initializeLanguageSelector();
|
||||||
|
|
||||||
|
// Initialiseer chat app (simpel)
|
||||||
|
initializeChatApp();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vul de sidebar explanation in
|
||||||
|
*/
|
||||||
|
function fillSidebarExplanation() {
|
||||||
|
const sidebarElement = document.getElementById('sidebar-explanation');
|
||||||
|
if (sidebarElement && window.chatConfig.explanation) {
|
||||||
|
if (typeof window.marked === 'function') {
|
||||||
|
sidebarElement.innerHTML = window.marked(window.chatConfig.explanation);
|
||||||
|
} else if (window.marked && typeof window.marked.parse === 'function') {
|
||||||
|
sidebarElement.innerHTML = window.marked.parse(window.chatConfig.explanation.replace(/\[\[(.*?)\]\]/g, '<strong>$1</strong>'));
|
||||||
|
} else {
|
||||||
|
sidebarElement.innerHTML = window.chatConfig.explanation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialiseert de language selector
|
||||||
|
*/
|
||||||
|
function initializeLanguageSelector() {
|
||||||
|
console.log('🔍 [DEBUG] Start initializeLanguageSelector');
|
||||||
|
|
||||||
|
const container = document.getElementById('language-selector-container');
|
||||||
|
console.log('🔍 [DEBUG] Container element:', container);
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('#language-selector-container niet gevonden');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Maak props voor de component
|
||||||
|
const props = {
|
||||||
|
initialLanguage: window.chatConfig.language || 'nl',
|
||||||
|
supportedLanguageDetails: window.chatConfig.supportedLanguageDetails || {},
|
||||||
|
allowedLanguages: window.chatConfig.allowedLanguages || ['nl', 'en', 'fr', 'de']
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] Props voor LanguageSelector:', JSON.stringify(props, null, 2));
|
||||||
|
|
||||||
|
// Mount de component direct - BELANGRIJK: we gebruiken window.Vue als dat beschikbaar is
|
||||||
|
// Dit is nodig voor compatibiliteit met oude code
|
||||||
|
const app = window.Vue && typeof window.Vue.createApp === 'function'
|
||||||
|
? window.Vue.createApp(LanguageSelector, props)
|
||||||
|
: createApp(LanguageSelector, props);
|
||||||
|
|
||||||
|
// Registreer error handler
|
||||||
|
app.config.errorHandler = (err, vm, info) => {
|
||||||
|
console.error('🚨 [Vue Error]', err);
|
||||||
|
console.error('Component:', vm);
|
||||||
|
console.error('Error Info:', info);
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Mount de component
|
||||||
|
const mountedApp = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] LanguageSelector instantie gemount:', mountedApp);
|
||||||
|
} catch (mountError) {
|
||||||
|
console.error('🚨 [ERROR] Fout bij mounten van LanguageSelector met Vue:', mountError);
|
||||||
|
console.log('🔍 [DEBUG] Probeer alternatieve direct DOM rendering...');
|
||||||
|
|
||||||
|
// Probeer de legacy renderComponent methode als Vue mounting mislukt
|
||||||
|
if (typeof LanguageSelector.renderComponent === 'function') {
|
||||||
|
console.log('🔍 [DEBUG] LanguageSelector.renderComponent gevonden, directe rendering uitvoeren');
|
||||||
|
try {
|
||||||
|
LanguageSelector.renderComponent(container, props);
|
||||||
|
console.log('🔍 [DEBUG] LanguageSelector direct gerenderd via renderComponent');
|
||||||
|
} catch (renderError) {
|
||||||
|
console.error('🚨 [ERROR] Ook alternatieve rendering gefaald:', renderError);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('🚨 [ERROR] Geen renderComponent methode beschikbaar op LanguageSelector');
|
||||||
|
|
||||||
|
// Noodoplossing: Handmatige DOM manipulatie
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="language-selector">
|
||||||
|
<label for="language-select">Taal / Language:</label>
|
||||||
|
<div class="select-wrapper">
|
||||||
|
<select id="language-select" class="language-select">
|
||||||
|
<option value="nl" selected>🇳🇱 Nederlands</option>
|
||||||
|
<option value="en">🇬🇧 English</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Event listener voor de fallback oplossing
|
||||||
|
const selectElement = container.querySelector('#language-select');
|
||||||
|
if (selectElement) {
|
||||||
|
selectElement.addEventListener('change', (e) => {
|
||||||
|
const newLanguage = e.target.value;
|
||||||
|
console.log(`Taal gewijzigd naar ${newLanguage} (via fallback)`);
|
||||||
|
|
||||||
|
// Update chatConfig
|
||||||
|
if (window.chatConfig) {
|
||||||
|
window.chatConfig.language = newLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stuur event voor andere componenten
|
||||||
|
const globalEvent = new CustomEvent('language-changed', {
|
||||||
|
detail: { language: newLanguage }
|
||||||
|
});
|
||||||
|
document.dispatchEvent(globalEvent);
|
||||||
|
|
||||||
|
// Sla voorkeur op
|
||||||
|
localStorage.setItem('preferredLanguage', newLanguage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Language change event listener
|
||||||
|
document.addEventListener('vue:language-changed', function(event) {
|
||||||
|
const newLanguage = event.detail.language;
|
||||||
|
console.log(`Taal gewijzigd naar ${newLanguage}`);
|
||||||
|
|
||||||
|
// Update chatConfig
|
||||||
|
if (window.chatConfig) {
|
||||||
|
window.chatConfig.language = newLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stuur event voor andere componenten
|
||||||
|
const globalEvent = new CustomEvent('language-changed', {
|
||||||
|
detail: { language: newLanguage }
|
||||||
|
});
|
||||||
|
document.dispatchEvent(globalEvent);
|
||||||
|
|
||||||
|
// Sla voorkeur op
|
||||||
|
localStorage.setItem('preferredLanguage', newLanguage);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] Language selector setup voltooid');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [CRITICAL ERROR] Bij initialiseren language selector:', error);
|
||||||
|
console.error('Stack trace:', error.stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialiseert de chat app (Vue component)
|
||||||
|
*/
|
||||||
|
function initializeChatApp() {
|
||||||
|
console.log('🔍 [DEBUG] Start initializeChatApp');
|
||||||
|
|
||||||
|
const container = document.querySelector('.chat-container');
|
||||||
|
console.log('🔍 [DEBUG] Chat container element:', container);
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.error('.chat-container niet gevonden');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Controleer of componenten beschikbaar zijn en log debug informatie
|
||||||
|
console.log('🔍 [DEBUG] ChatApp component beschikbaar:', ChatApp);
|
||||||
|
console.log('🔍 [DEBUG] Geïmporteerde componenten:', Object.keys(Components));
|
||||||
|
console.log('🔍 [DEBUG] MessageHistory component:', Components.MessageHistory);
|
||||||
|
console.log('🔍 [DEBUG] ChatInput component:', Components.ChatInput);
|
||||||
|
|
||||||
|
// Geen workarounds voor Popper nodig
|
||||||
|
|
||||||
|
// Controleer of renderComponent methoden beschikbaar zijn
|
||||||
|
console.log('🔍 [DEBUG] MessageHistory.renderComponent beschikbaar:',
|
||||||
|
typeof Components.MessageHistory.renderComponent === 'function');
|
||||||
|
console.log('🔍 [DEBUG] ChatInput.renderComponent beschikbaar:',
|
||||||
|
typeof Components.ChatInput.renderComponent === 'function');
|
||||||
|
|
||||||
|
if (!ChatApp) {
|
||||||
|
throw new Error('ChatApp component niet gevonden');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extra verificatie dat alle sub-componenten beschikbaar zijn
|
||||||
|
if (!Components.MessageHistory || !Components.ChatInput ||
|
||||||
|
!Components.TypingIndicator || !Components.ChatMessage) {
|
||||||
|
console.warn('⚠️ [WARN] Niet alle benodigde sub-componenten zijn geladen!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maak props voor de component
|
||||||
|
const props = {
|
||||||
|
apiPrefix: window.chatConfig.apiPrefix || '',
|
||||||
|
conversationId: window.chatConfig.conversationId || 'default',
|
||||||
|
userId: window.chatConfig.userId || null,
|
||||||
|
userName: window.chatConfig.userName || '',
|
||||||
|
initialLanguage: window.chatConfig.language || 'nl',
|
||||||
|
supportedLanguageDetails: window.chatConfig.supportedLanguageDetails || {},
|
||||||
|
allowedLanguages: window.chatConfig.allowedLanguages || ['nl', 'en', 'fr', 'de']
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] Alle componenten registreren voor ChatApp...');
|
||||||
|
|
||||||
|
console.log('🔍 [DEBUG] Props voor ChatApp:', JSON.stringify(props, null, 2));
|
||||||
|
|
||||||
|
// Mount de component met alle nodige componenten
|
||||||
|
const app = createApp(ChatApp, props);
|
||||||
|
|
||||||
|
// Registreer alle componenten globaal
|
||||||
|
Object.entries(Components).forEach(([name, component]) => {
|
||||||
|
console.log(`🔍 [DEBUG] Registreer component globaal: ${name}`);
|
||||||
|
app.component(name, component);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Registreer error handler
|
||||||
|
app.config.errorHandler = (err, vm, info) => {
|
||||||
|
console.error('🚨 [Vue Error in ChatApp]', err);
|
||||||
|
console.error('Component:', vm);
|
||||||
|
console.error('Error Info:', info);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log app object voor debugging
|
||||||
|
console.log('🔍 [DEBUG] ChatApp Vue app object:', app);
|
||||||
|
console.log('🔍 [DEBUG] App.mount functie:', typeof app.mount);
|
||||||
|
|
||||||
|
// Mount de component
|
||||||
|
const mountedApp = app.mount(container);
|
||||||
|
console.log('🔍 [DEBUG] ChatApp gemount, instance:', mountedApp);
|
||||||
|
|
||||||
|
// Bewaar referentie globaal voor debugging
|
||||||
|
window.__chatApp = mountedApp;
|
||||||
|
|
||||||
|
// Bewaar een referentie naar de Vue instantie voor gebruik door andere componenten
|
||||||
|
window.__vueApp = app;
|
||||||
|
console.log('🔍 [DEBUG] Vue app instance globaal beschikbaar als window.__vueApp');
|
||||||
|
|
||||||
|
// Log belangrijke methods van de gemounte component
|
||||||
|
console.log('🔍 [DEBUG] Belangrijke ChatApp methods beschikbaar:', {
|
||||||
|
renderComponent: typeof mountedApp.renderComponent === 'function',
|
||||||
|
initializeChat: typeof mountedApp.initializeChat === 'function'
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [CRITICAL ERROR] Bij initialiseren chat app:', error);
|
||||||
|
console.error('Stack trace:', error.stack);
|
||||||
|
|
||||||
|
// Fallback naar placeholder
|
||||||
|
container.innerHTML = '<div>Fout bij het initialiseren van de chat applicatie</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Chat client modules geladen en gebundeld met moderne ES module structuur.');
|
||||||
@@ -20,6 +20,18 @@
|
|||||||
"@parcel/transformer-sass": "^2.15.2",
|
"@parcel/transformer-sass": "^2.15.2",
|
||||||
"parcel": "^2.15.2"
|
"parcel": "^2.15.2"
|
||||||
},
|
},
|
||||||
|
"alias": {
|
||||||
|
"vue": "vue/dist/vue.esm-bundler.js"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 0.5%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not dead"
|
||||||
|
],
|
||||||
|
"@parcel/transformer-js": {
|
||||||
|
"inlineFS": true,
|
||||||
|
"inlineEnvironment": ["NODE_ENV"]
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prebuild": "mkdir -p static/dist && cp -r ../eveai_app/static/assets static/",
|
"prebuild": "mkdir -p static/dist && cp -r ../eveai_app/static/assets static/",
|
||||||
"build": "npm run prebuild && npm run build:main && npm run build:chat",
|
"build": "npm run prebuild && npm run build:main && npm run build:chat",
|
||||||
|
|||||||
Reference in New Issue
Block a user