/**
* ds-ai-chat-sidebar.js
* AI Chat Sidebar wrapper component
* Wraps ds-chat-panel with collapse/expand toggle and context binding
* MVP2: Right sidebar integrated with 3-column layout
*/
import contextStore from '../../stores/context-store.js';
import { useUserStore } from '../../stores/user-store.js';
class DSAiChatSidebar extends HTMLElement {
constructor() {
super();
this.userStore = useUserStore();
const preferences = this.userStore.getPreferences();
this.isCollapsed = preferences.chatCollapsedState !== false; // Default to collapsed
this.currentProject = null;
this.currentTeam = null;
this.currentPage = null;
}
connectedCallback() {
this.render();
this.setupEventListeners();
this.initializeContextSubscriptions();
}
initializeContextSubscriptions() {
// Subscribe to context changes to update chat panel context
this.unsubscribe = contextStore.subscribe(({ state }) => {
this.currentProject = state.project;
this.currentTeam = state.team;
this.currentPage = state.page;
// Update chat panel with current context
const chatPanel = this.querySelector('ds-chat-panel');
if (chatPanel && chatPanel.setContext) {
chatPanel.setContext({
project: this.currentProject,
team: this.currentTeam,
page: this.currentPage
});
}
});
// Get initial context
const context = contextStore.getState();
if (context) {
this.currentProject = context.currentProject || context.project || null;
this.currentTeam = context.teamId || context.team || null;
this.currentPage = context.page || null;
}
}
render() {
const buttonClass = this.isCollapsed ? 'rotating' : '';
this.innerHTML = `
${this.isCollapsed ? `
` : ''}
`;
}
async setupEventListeners() {
// Handle both expanded and collapsed toggle buttons
const toggleBtn = this.querySelector('#toggle-collapse-btn');
const toggleBtnCollapsed = this.querySelector('#toggle-collapse-btn-collapsed');
const attachToggleListener = (btn) => {
if (btn) {
btn.addEventListener('click', () => {
this.toggleCollapse();
});
btn.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
btn.click();
}
});
}
};
attachToggleListener(toggleBtn);
attachToggleListener(toggleBtnCollapsed);
// Hydrate chat panel on first connection
const chatContainer = this.querySelector('#chat-panel-container');
if (chatContainer && chatContainer.children.length === 0) {
try {
// Import component registry to load chat panel
const { hydrateComponent } = await import('../../config/component-registry.js');
await hydrateComponent('ds-chat-panel', chatContainer);
console.log('[DSAiChatSidebar] Chat panel loaded');
// Set initial context on chat panel
const chatPanel = chatContainer.querySelector('ds-chat-panel');
if (chatPanel && chatPanel.setContext) {
chatPanel.setContext({
project: this.currentProject,
team: this.currentTeam,
page: this.currentPage
});
}
} catch (error) {
console.error('[DSAiChatSidebar] Failed to load chat panel:', error);
chatContainer.innerHTML = `
Failed to load chat panel
`;
}
}
}
toggleCollapse() {
this.isCollapsed = !this.isCollapsed;
// Persist chat collapsed state to userStore
this.userStore.updatePreferences({ chatCollapsedState: this.isCollapsed });
// Update CSS class for smooth CSS transition (avoid re-render for better UX)
if (this.isCollapsed) {
this.classList.add('collapsed');
} else {
this.classList.remove('collapsed');
}
// Update button classes for rotation animation
const btns = this.querySelectorAll('.ai-chat-toggle-btn');
btns.forEach(btn => {
if (this.isCollapsed) {
btn.classList.add('rotating');
} else {
btn.classList.remove('rotating');
}
btn.setAttribute('aria-expanded', String(!this.isCollapsed));
});
// Update header and content visibility with inline styles
const header = this.querySelector('[style*="padding: 12px"]');
const content = this.querySelector('.chat-content');
if (header) {
if (this.isCollapsed) {
header.style.display = 'none';
} else {
header.style.display = 'flex';
}
}
if (content) {
if (this.isCollapsed) {
content.style.display = 'none';
} else {
content.style.display = 'flex';
}
}
// Toggle collapsed button visibility
let collapsedBtn = this.querySelector('#toggle-collapse-btn-collapsed');
if (!collapsedBtn && this.isCollapsed) {
// Create the collapsed button if needed
this.render();
this.setupEventListeners();
} else if (collapsedBtn && !this.isCollapsed) {
// Remove the collapsed button if needed
this.render();
this.setupEventListeners();
}
// Dispatch event for layout adjustment
this.dispatchEvent(new CustomEvent('chat-sidebar-toggled', {
detail: { isCollapsed: this.isCollapsed },
bubbles: true,
composed: true
}));
}
disconnectedCallback() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
}
customElements.define('ds-ai-chat-sidebar', DSAiChatSidebar);