import * as plugins from '../wcctools.plugins.js'; import { DeesElement, property, html, customElement, type TemplateResult, state } from '@design.estate/dees-element'; import { WccDashboard, getSectionItems } from './wcc-dashboard.js'; import type { TTemplateFactory } from './wcctools.helpers.js'; import { getDemoCount, hasMultipleDemos } from './wcctools.helpers.js'; import type { IWccSection, TElementType } from '../wcctools.interfaces.js'; @customElement('wcc-sidebar') export class WccSidebar extends DeesElement { @property({ attribute: false }) accessor selectedItem: DeesElement | TTemplateFactory; @property({ attribute: false }) accessor selectedType: TElementType; @property() accessor dashboardRef: WccDashboard; @property() accessor isNative: boolean = false; // Track which elements are expanded (for multi-demo elements) @state() accessor expandedElements: Set = new Set(); // Track which sections are collapsed @state() accessor collapsedSections: Set = new Set(); private sectionsInitialized = false; public render(): TemplateResult { return html` `; } /** * Initialize collapsed sections from section config */ private initCollapsedSections() { if (this.sectionsInitialized) return; const collapsed = new Set(); for (const section of this.dashboardRef.sections) { if (section.collapsed) { collapsed.add(section.name); } } this.collapsedSections = collapsed; this.sectionsInitialized = true; } /** * Render all sections */ private renderSections() { this.initCollapsedSections(); return this.dashboardRef.sections.map((section, index) => { const isCollapsed = this.collapsedSections.has(section.name); const sectionIcon = section.icon || (section.type === 'pages' ? 'insert_drive_file' : 'widgets'); return html`
this.toggleSectionCollapsed(section.name)} > expand_more ${section.icon ? html`${section.icon}` : null} ${section.name}
${this.renderSectionItems(section)}
`; }); } /** * Render items for a section */ private renderSectionItems(section: IWccSection) { const entries = getSectionItems(section); if (section.type === 'pages') { return entries.map(([pageName, item]) => { return html`
{ await plugins.deesDomtools.DomTools.setupDomTools(); this.selectItem('page', pageName, item, 0, section); }} > insert_drive_file
${pageName}
`; }); } else { // type === 'elements' return entries.map(([elementName, item]) => { const anonItem = item as any; const demoCount = anonItem.demo ? getDemoCount(anonItem.demo) : 0; const isMultiDemo = anonItem.demo && hasMultipleDemos(anonItem.demo); const isExpanded = this.expandedElements.has(elementName); const isSelected = this.selectedItem === item; if (isMultiDemo) { // Multi-demo element - render as expandable folder return html`
this.toggleExpanded(elementName)} > chevron_right folder
${elementName}
${isExpanded ? html`
${Array.from({ length: demoCount }, (_, i) => { const demoIndex = i; const isThisDemoSelected = isSelected && this.dashboardRef.selectedDemoIndex === demoIndex; return html`
{ await plugins.deesDomtools.DomTools.setupDomTools(); this.selectItem('element', elementName, item, demoIndex, section); }} > play_circle
demo${demoIndex + 1}
`; })}
` : null} `; } else { // Single demo element return html`
{ await plugins.deesDomtools.DomTools.setupDomTools(); this.selectItem('element', elementName, item, 0, section); }} > featured_video
${elementName}
`; } }); } } private toggleSectionCollapsed(sectionName: string) { const newSet = new Set(this.collapsedSections); if (newSet.has(sectionName)) { newSet.delete(sectionName); } else { newSet.add(sectionName); } this.collapsedSections = newSet; } private toggleExpanded(elementName: string) { const newSet = new Set(this.expandedElements); if (newSet.has(elementName)) { newSet.delete(elementName); } else { newSet.add(elementName); } this.expandedElements = newSet; } protected updated(changedProperties: Map) { super.updated(changedProperties); // Auto-expand folder when a multi-demo element is selected if (changedProperties.has('selectedItem') && this.selectedItem) { // Find the element in any section for (const section of this.dashboardRef.sections) { if (section.type !== 'elements') continue; const entries = getSectionItems(section); const found = entries.find(([_, item]) => item === this.selectedItem); if (found) { const [elementName, item] = found; const anonItem = item as any; if (anonItem.demo && hasMultipleDemos(anonItem.demo)) { if (!this.expandedElements.has(elementName)) { const newSet = new Set(this.expandedElements); newSet.add(elementName); this.expandedElements = newSet; } } break; } } } } public selectItem( typeArg: TElementType, itemNameArg: string, itemArg: TTemplateFactory | DeesElement, demoIndex: number = 0, section?: IWccSection ) { console.log('selected item'); console.log(itemNameArg); console.log(itemArg); console.log('demo index:', demoIndex); console.log('section:', section?.name); this.selectedItem = itemArg; this.selectedType = typeArg; this.dashboardRef.selectedDemoIndex = demoIndex; // Set the selected section on dashboard if (section) { this.dashboardRef.selectedSection = section; } this.dispatchEvent( new CustomEvent('selectedType', { detail: typeArg }) ); this.dispatchEvent( new CustomEvent('selectedItemName', { detail: itemNameArg }) ); this.dispatchEvent( new CustomEvent('selectedItem', { detail: itemArg }) ); this.dashboardRef.buildUrl(); // Force re-render to update demo child selection indicator this.requestUpdate(); } }