Files
dss/admin-ui/js/components/listings/ds-component-list.js
Digital Production Factory 276ed71f31 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
2025-12-09 18:45:48 -03:00

191 lines
6.7 KiB
JavaScript

/**
* ds-component-list.js
* Component listing and management interface
* Shows all components with links to Storybook and adoption stats
*/
import URLBuilder from '../../utils/url-builder.js';
export default class ComponentList extends HTMLElement {
constructor() {
super();
this.components = [
{ id: 'button', name: 'Button', category: 'Inputs', adoption: 95, variants: 12 },
{ id: 'input', name: 'Input Field', category: 'Inputs', adoption: 88, variants: 8 },
{ id: 'card', name: 'Card', category: 'Containers', adoption: 92, variants: 5 },
{ id: 'modal', name: 'Modal', category: 'Containers', adoption: 78, variants: 3 },
{ id: 'badge', name: 'Badge', category: 'Status', adoption: 85, variants: 6 },
{ id: 'tooltip', name: 'Tooltip', category: 'Helpers', adoption: 72, variants: 4 },
{ id: 'dropdown', name: 'Dropdown', category: 'Inputs', adoption: 81, variants: 4 },
{ id: 'pagination', name: 'Pagination', category: 'Navigation', adoption: 65, variants: 2 },
];
this.selectedCategory = 'All';
}
connectedCallback() {
this.render();
this.setupEventListeners();
}
render() {
this.innerHTML = `
<div style="padding: 24px; height: 100%; overflow-y: auto;">
<div style="margin-bottom: 24px;">
<h1 style="margin: 0 0 8px 0; font-size: 24px;">Design System Components</h1>
<p style="margin: 0; color: var(--vscode-text-dim);">
Browse, preview, and track component adoption
</p>
</div>
<!-- Filter Bar -->
<div style="margin-bottom: 24px; display: flex; gap: 8px; flex-wrap: wrap;">
<button class="filter-btn" data-category="All" style="
padding: 6px 12px;
background: var(--vscode-selection);
color: var(--vscode-foreground);
border: 1px solid var(--vscode-focusBorder);
border-radius: 4px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
">All</button>
${['Inputs', 'Containers', 'Status', 'Helpers', 'Navigation'].map(cat => `
<button class="filter-btn" data-category="${cat}" style="
padding: 6px 12px;
background: var(--vscode-sidebar);
color: var(--vscode-foreground);
border: 1px solid var(--vscode-border);
border-radius: 4px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
">${cat}</button>
`).join('')}
</div>
<!-- Components Grid -->
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px;">
${this.renderComponents()}
</div>
</div>
`;
}
renderComponents() {
const filtered = this.selectedCategory === 'All'
? this.components
: this.components.filter(c => c.category === this.selectedCategory);
return filtered.map(component => `
<div style="
background: var(--vscode-sidebar);
border: 1px solid var(--vscode-border);
border-radius: 4px;
overflow: hidden;
">
<!-- Header -->
<div style="
background: var(--vscode-bg);
padding: 12px;
border-bottom: 1px solid var(--vscode-border);
">
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 8px;">
<div>
<div style="font-weight: 600; font-size: 14px; margin-bottom: 2px;">
${component.name}
</div>
<div style="font-size: 11px; color: var(--vscode-text-dim);">
${component.category}
</div>
</div>
<span style="
background: #4caf50;
color: white;
padding: 2px 8px;
border-radius: 3px;
font-size: 10px;
font-weight: 600;
">${component.adoption}%</span>
</div>
</div>
<!-- Content -->
<div style="padding: 12px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 12px; font-size: 12px;">
<span>Variants: <strong>${component.variants}</strong></span>
<span>Adoption: <strong>${component.adoption}%</strong></span>
</div>
<!-- Progress Bar -->
<div style="width: 100%; height: 4px; background: var(--vscode-bg); border-radius: 2px; overflow: hidden; margin-bottom: 12px;">
<div style="width: ${component.adoption}%; height: 100%; background: #4caf50;"></div>
</div>
<!-- Actions -->
<div style="display: flex; gap: 8px;">
<button class="storybook-btn" data-component-id="${component.id}" style="
flex: 1;
padding: 6px;
background: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border: none;
border-radius: 3px;
cursor: pointer;
font-size: 11px;
font-weight: 500;
">📖 Storybook</button>
<button class="edit-btn" data-component-id="${component.id}" style="
flex: 1;
padding: 6px;
background: var(--vscode-button-secondaryBackground);
color: var(--vscode-button-secondaryForeground);
border: none;
border-radius: 3px;
cursor: pointer;
font-size: 11px;
font-weight: 500;
">✏️ Edit</button>
</div>
</div>
</div>
`).join('');
}
setupEventListeners() {
// Filter buttons
this.querySelectorAll('.filter-btn').forEach(btn => {
btn.addEventListener('click', () => {
this.selectedCategory = btn.dataset.category;
this.render();
this.setupEventListeners();
});
});
// Storybook buttons
this.querySelectorAll('.storybook-btn').forEach(btn => {
btn.addEventListener('click', () => {
const componentId = btn.dataset.componentId;
const component = this.components.find(c => c.id === componentId);
if (component) {
const url = URLBuilder.getComponentUrl(component);
window.open(url, '_blank');
}
});
});
// Edit buttons
this.querySelectorAll('.edit-btn').forEach(btn => {
btn.addEventListener('click', () => {
const componentId = btn.dataset.componentId;
this.dispatchEvent(new CustomEvent('edit-component', {
detail: { componentId },
bubbles: true,
composed: true
}));
});
});
}
}
customElements.define('ds-component-list', ComponentList);