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:
190
admin-ui/js/components/listings/ds-component-list.js
Normal file
190
admin-ui/js/components/listings/ds-component-list.js
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* 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);
|
||||
Reference in New Issue
Block a user