/** * Conversation Sidebar Component * Conversation Sidebar component */ const ConversationSidebar = { template: `
Today
{{ conv.title }}
{{ conv.gene_family }} {{ conv.message_count }} messages
{{ conv.last_message }}
Yesterday
{{ conv.title }}
{{ conv.gene_family }} {{ conv.message_count }}
Past 7 days
{{ conv.title }}
{{ conv.gene_family }}

No conversations yet

Click "New Chat" to start gene family analysis

`, props: { userId: { type: String, default: 'xia-lab' }, apiBaseUrl: { type: String, default: 'http://localhost:8000/api' } }, data() { return { isCollapsed: false, searchQuery: '', conversations: [], currentConversationId: null, loading: false, // Icons Plus: ElementPlusIconsVue.Plus, ArrowLeft: ElementPlusIconsVue.ArrowLeft, ArrowRight: ElementPlusIconsVue.ArrowRight, ChatDotRound: ElementPlusIconsVue.ChatDotRound, ChatLineRound: ElementPlusIconsVue.ChatLineRound, More: ElementPlusIconsVue.More, Edit: ElementPlusIconsVue.Edit, Folder: ElementPlusIconsVue.Folder, Delete: ElementPlusIconsVue.Delete, UserFilled: ElementPlusIconsVue.UserFilled, } }, computed: { filteredConversations() { if (!this.searchQuery) return this.conversations; const query = this.searchQuery.toLowerCase(); return this.conversations.filter(conv => conv.title.toLowerCase().includes(query) || (conv.gene_family && conv.gene_family.toLowerCase().includes(query)) || conv.last_message.toLowerCase().includes(query) ); }, todayConversations() { const today = new Date().toDateString(); return this.filteredConversations.filter(conv => { const convDate = new Date(conv.updated_at).toDateString(); return convDate === today; }); }, yesterdayConversations() { const yesterday = new Date(Date.now() - 86400000).toDateString(); return this.filteredConversations.filter(conv => { const convDate = new Date(conv.updated_at).toDateString(); return convDate === yesterday; }); }, olderConversations() { const yesterday = new Date(Date.now() - 86400000).toDateString(); return this.filteredConversations.filter(conv => { const convDate = new Date(conv.updated_at).toDateString(); return convDate < yesterday; }); } }, mounted() { this.loadConversations(); // Auto-refresh this.refreshInterval = setInterval(() => { this.loadConversations(); }, 30000); // 30 seconds refresh interval }, beforeUnmount() { if (this.refreshInterval) { clearInterval(this.refreshInterval); } }, methods: { async loadConversations() { try { this.loading = true; const response = await fetch(`${this.apiBaseUrl}/conversations/list/${this.userId}`); if (response.ok) { const data = await response.json(); this.conversations = data.conversations || []; } } catch (error) { console.error('Failed to load conversations:', error); // Use mock data this.conversations = this.getMockConversations(); } finally { this.loading = false; } }, getMockConversations() { // Mock data for testing return [ { conversation_id: 'conv_001', title: 'At.WRKY gene family analysis', gene_family: 'WRKY', species: 'At', message_count: 12, last_message: 'Phylogenetic tree done', updated_at: new Date().toISOString() }, { conversation_id: 'conv_002', title: 'Os.TCP evolution analysis', gene_family: 'TCP', species: 'Os', message_count: 5, last_message: 'Building tree...', updated_at: new Date(Date.now() - 3600000).toISOString() }, { conversation_id: 'conv_003', title: 'HMMER config consultation', message_count: 8, last_message: 'E-value 1e-5 recommended', updated_at: new Date(Date.now() - 86400000).toISOString() } ]; }, toggleSidebar() { this.isCollapsed = !this.isCollapsed; this.$emit('toggle', this.isCollapsed); }, async createNewConversation() { try { const response = await fetch(`${this.apiBaseUrl}/conversations/create`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ user_id: this.userId, title: 'New Chat ' + new Date().toLocaleTimeString() }) }); if (response.ok) { const data = await response.json(); this.currentConversationId = data.conversation_id; this.$emit('new-conversation', data); await this.loadConversations(); } } catch (error) { console.error('Failed to create conversation:', error); // Create local conversation const newConv = { conversation_id: 'conv_' + Date.now(), title: 'New Chat', message_count: 0, last_message: '', updated_at: new Date().toISOString() }; this.conversations.unshift(newConv); this.currentConversationId = newConv.conversation_id; this.$emit('new-conversation', newConv); } }, selectConversation(conv) { this.currentConversationId = conv.conversation_id; this.$emit('select-conversation', conv); }, async renameConversation(conv) { const newTitle = prompt('Enter new title:', conv.title); if (newTitle && newTitle !== conv.title) { try { await fetch(`${this.apiBaseUrl}/conversations/update-title`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ conversation_id: conv.conversation_id, title: newTitle }) }); conv.title = newTitle; } catch (error) { console.error('Failed to rename:', error); conv.title = newTitle; // local update } } }, async archiveConversation(conv) { try { await fetch(`${this.apiBaseUrl}/conversations/archive`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ conversation_id: conv.conversation_id }) }); await this.loadConversations(); } catch (error) { console.error('Failed to archive:', error); } }, async deleteConversation(conv) { if (confirm(`Delete conversation "${conv.title}"?`)) { try { await fetch(`${this.apiBaseUrl}/conversations/delete`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ conversation_id: conv.conversation_id }) }); await this.loadConversations(); if (this.currentConversationId === conv.conversation_id) { this.currentConversationId = null; this.$emit('select-conversation', null); } } catch (error) { console.error('Failed to delete:', error); } } } } }; // Export component if (typeof module !== 'undefined' && module.exports) { module.exports = { ConversationSidebar }; }