Initial commit: Clean DSS implementation
Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm
Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)
Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability
Migration completed: $(date)
🤖 Clean migration with full functionality preserved
This commit is contained in:
120
admin-ui/js/components/layout/ds-panel.js
Normal file
120
admin-ui/js/components/layout/ds-panel.js
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* ds-panel.js
|
||||
* Bottom panel component - holds team-specific tabs
|
||||
*/
|
||||
|
||||
import { getPanelConfig } from '../../config/panel-config.js';
|
||||
|
||||
class DSPanel extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.currentTab = null;
|
||||
this.tabs = [];
|
||||
this.advancedMode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure panel with team-specific tabs
|
||||
* @param {string} teamId - Team identifier (ui, ux, qa, admin)
|
||||
* @param {boolean} advancedMode - Whether advanced mode is enabled
|
||||
*/
|
||||
configure(teamId, advancedMode = false) {
|
||||
this.advancedMode = advancedMode;
|
||||
this.tabs = getPanelConfig(teamId, advancedMode);
|
||||
|
||||
// Set first tab as current if not already set
|
||||
if (this.tabs.length > 0 && !this.currentTab) {
|
||||
this.currentTab = this.tabs[0].id;
|
||||
}
|
||||
|
||||
// Re-render with new configuration
|
||||
this.render();
|
||||
this.setupEventListeners();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
this.setupEventListeners();
|
||||
}
|
||||
|
||||
render() {
|
||||
this.innerHTML = `
|
||||
<div class="panel-header">
|
||||
${this.tabs.map(tab => `
|
||||
<div class="panel-tab ${tab.id === this.currentTab ? 'active' : ''}"
|
||||
data-tab="${tab.id}">
|
||||
${tab.label}
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
<div id="panel-tab-content">
|
||||
${this.renderTabContent(this.currentTab)}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
this.querySelectorAll('.panel-tab').forEach(tab => {
|
||||
tab.addEventListener('click', (e) => {
|
||||
const tabId = e.currentTarget.dataset.tab;
|
||||
this.switchTab(tabId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
switchTab(tabId) {
|
||||
if (tabId === this.currentTab) return;
|
||||
|
||||
this.currentTab = tabId;
|
||||
|
||||
// Update active state
|
||||
this.querySelectorAll('.panel-tab').forEach(tab => {
|
||||
tab.classList.toggle('active', tab.dataset.tab === tabId);
|
||||
});
|
||||
|
||||
// Update content
|
||||
const content = this.querySelector('#panel-tab-content');
|
||||
if (content) {
|
||||
content.innerHTML = this.renderTabContent(tabId);
|
||||
}
|
||||
|
||||
// Dispatch tab-switch event
|
||||
this.dispatchEvent(new CustomEvent('panel-tab-switch', {
|
||||
bubbles: true,
|
||||
detail: { tab: tabId }
|
||||
}));
|
||||
}
|
||||
|
||||
renderTabContent(tabId) {
|
||||
// Find tab configuration
|
||||
const tabConfig = this.tabs.find(tab => tab.id === tabId);
|
||||
if (!tabConfig) {
|
||||
return '<div style="padding: 16px; color: var(--vscode-text-dim);">Tab not found</div>';
|
||||
}
|
||||
|
||||
// Dynamically create component based on configuration
|
||||
const componentTag = tabConfig.component;
|
||||
const propsString = Object.entries(tabConfig.props || {})
|
||||
.map(([key, value]) => `${key}="${value}"`)
|
||||
.join(' ');
|
||||
|
||||
return `<${componentTag} ${propsString}></${componentTag}>`;
|
||||
}
|
||||
|
||||
// Public method for workdesks to update panel content
|
||||
setTabContent(tabId, content) {
|
||||
const tabContent = this.querySelector('#panel-tab-content');
|
||||
if (this.currentTab === tabId && tabContent) {
|
||||
if (typeof content === 'string') {
|
||||
tabContent.innerHTML = content;
|
||||
} else {
|
||||
tabContent.innerHTML = '';
|
||||
tabContent.appendChild(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('ds-panel', DSPanel);
|
||||
Reference in New Issue
Block a user