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:
196
admin-ui/js/config/component-registry.js
Normal file
196
admin-ui/js/config/component-registry.js
Normal file
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* component-registry.js
|
||||
* MVP1: Lazy-loading registry for panel components
|
||||
* Components are loaded on-demand to improve performance
|
||||
*/
|
||||
|
||||
/**
|
||||
* Component registry maps tag names to dynamic import paths
|
||||
* Format: { 'tag-name': () => import('path/to/component.js') }
|
||||
*/
|
||||
export const COMPONENT_REGISTRY = {
|
||||
// Tools components
|
||||
'ds-metrics-panel': () => import('../components/tools/ds-metrics-panel.js'),
|
||||
'ds-console-viewer': () => import('../components/tools/ds-console-viewer.js'),
|
||||
'ds-token-inspector': () => import('../components/tools/ds-token-inspector.js'),
|
||||
'ds-figma-status': () => import('../components/tools/ds-figma-status.js'),
|
||||
'ds-activity-log': () => import('../components/tools/ds-activity-log.js'),
|
||||
'ds-visual-diff': () => import('../components/tools/ds-visual-diff.js'),
|
||||
'ds-accessibility-report': () => import('../components/tools/ds-accessibility-report.js'),
|
||||
'ds-screenshot-gallery': () => import('../components/tools/ds-screenshot-gallery.js'),
|
||||
'ds-network-monitor': () => import('../components/tools/ds-network-monitor.js'),
|
||||
'ds-test-results': () => import('../components/tools/ds-test-results.js'),
|
||||
'ds-system-log': () => import('../components/tools/ds-system-log.js'),
|
||||
|
||||
// Phase 6 Special Tools (MVP2)
|
||||
'ds-figma-extract-quick': () => import('../components/tools/ds-figma-extract-quick.js'),
|
||||
'ds-quick-wins-script': () => import('../components/tools/ds-quick-wins-script.js'),
|
||||
'ds-regression-testing': () => import('../components/tools/ds-regression-testing.js'),
|
||||
|
||||
// Other team-specific tools
|
||||
// UI Team Tools
|
||||
'ds-storybook-figma-compare': () => import('../components/tools/ds-storybook-figma-compare.js'),
|
||||
'ds-storybook-live-compare': () => import('../components/tools/ds-storybook-live-compare.js'),
|
||||
'ds-figma-extraction': () => import('../components/tools/ds-figma-extraction.js'),
|
||||
'ds-project-analysis': () => import('../components/tools/ds-project-analysis.js'),
|
||||
|
||||
// UX Team Tools
|
||||
'ds-figma-plugin': () => import('../components/tools/ds-figma-plugin.js'),
|
||||
'ds-token-list': () => import('../components/tools/ds-token-list.js'),
|
||||
'ds-asset-list': () => import('../components/tools/ds-asset-list.js'),
|
||||
'ds-component-list': () => import('../components/tools/ds-component-list.js'),
|
||||
'ds-navigation-demos': () => import('../components/tools/ds-navigation-demos.js'),
|
||||
|
||||
// QA Team Tools
|
||||
'ds-figma-live-compare': () => import('../components/tools/ds-figma-live-compare.js'),
|
||||
'ds-esre-editor': () => import('../components/tools/ds-esre-editor.js'),
|
||||
|
||||
// Chat components
|
||||
'ds-chat-panel': () => import('../components/tools/ds-chat-panel.js'),
|
||||
|
||||
// Metrics components
|
||||
'ds-frontpage': () => import('../components/metrics/ds-frontpage.js'),
|
||||
|
||||
// Admin components
|
||||
'ds-user-settings': () => import('../components/admin/ds-user-settings.js'),
|
||||
|
||||
// Additional UI & Layout Components
|
||||
'ds-action-bar': () => import('../components/ds-action-bar.js'),
|
||||
'ds-activity-bar': () => import('../components/layout/ds-activity-bar.js'),
|
||||
'ds-admin-settings': () => import('../components/admin/ds-admin-settings.js'),
|
||||
'ds-ai-chat-sidebar': () => import('../components/layout/ds-ai-chat-sidebar.js'),
|
||||
'ds-badge': () => import('../components/ds-badge.js'),
|
||||
'ds-base-tool': () => import('../components/base/ds-base-tool.js'),
|
||||
'ds-button': () => import('../components/ds-button.js'),
|
||||
'ds-card': () => import('../components/ds-card.js'),
|
||||
'ds-component-base': () => import('../components/ds-component-base.js'),
|
||||
'ds-input': () => import('../components/ds-input.js'),
|
||||
'ds-metric-card': () => import('../components/metrics/ds-metric-card.js'),
|
||||
'ds-metrics-dashboard': () => import('../components/metrics/ds-metrics-dashboard.js'),
|
||||
'ds-notification-center': () => import('../components/ds-notification-center.js'),
|
||||
'ds-panel': () => import('../components/layout/ds-panel.js'),
|
||||
'ds-project-list': () => import('../components/admin/ds-project-list.js'),
|
||||
'ds-project-selector': () => import('../components/layout/ds-project-selector.js'),
|
||||
'ds-quick-wins': () => import('../components/tools/ds-quick-wins.js'),
|
||||
'ds-shell': () => import('../components/layout/ds-shell.js'),
|
||||
'ds-toast': () => import('../components/ds-toast.js'),
|
||||
'ds-toast-provider': () => import('../components/ds-toast-provider.js'),
|
||||
'ds-workflow': () => import('../components/ds-workflow.js'),
|
||||
|
||||
// Listing Components
|
||||
'ds-icon-list': () => import('../components/listings/ds-icon-list.js'),
|
||||
'ds-jira-issues': () => import('../components/listings/ds-jira-issues.js'),
|
||||
};
|
||||
|
||||
// Track loaded components
|
||||
const loadedComponents = new Set();
|
||||
|
||||
/**
|
||||
* MVP1: Lazy-load and hydrate a component
|
||||
* @param {string} tagName - Component tag name (e.g., 'ds-metrics-panel')
|
||||
* @param {HTMLElement} container - Container to append component to
|
||||
* @returns {Promise<HTMLElement>} The created component element
|
||||
*/
|
||||
export async function hydrateComponent(tagName, container) {
|
||||
if (!COMPONENT_REGISTRY[tagName]) {
|
||||
console.warn(`[ComponentRegistry] Unknown component: ${tagName}`);
|
||||
throw new Error(`Component not found in registry: ${tagName}`);
|
||||
}
|
||||
|
||||
try {
|
||||
// Load component if not already loaded
|
||||
if (!loadedComponents.has(tagName)) {
|
||||
console.log(`[ComponentRegistry] Loading component: ${tagName}`);
|
||||
await COMPONENT_REGISTRY[tagName]();
|
||||
loadedComponents.add(tagName);
|
||||
}
|
||||
|
||||
// Verify component was registered as custom element
|
||||
if (!customElements.get(tagName)) {
|
||||
throw new Error(`Component ${tagName} loaded but not defined as custom element`);
|
||||
}
|
||||
|
||||
// Create and append element
|
||||
const element = document.createElement(tagName);
|
||||
if (container) {
|
||||
container.appendChild(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
} catch (error) {
|
||||
console.error(`[ComponentRegistry] Failed to hydrate ${tagName}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if component exists in registry
|
||||
* @param {string} tagName - Component tag name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isComponentRegistered(tagName) {
|
||||
return tagName in COMPONENT_REGISTRY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if component is already loaded
|
||||
* @param {string} tagName - Component tag name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isComponentLoaded(tagName) {
|
||||
return loadedComponents.has(tagName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered component tags
|
||||
* @returns {Array<string>} Array of component tag names
|
||||
*/
|
||||
export function getRegisteredComponents() {
|
||||
return Object.keys(COMPONENT_REGISTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload a component without instantiating it
|
||||
* @param {string} tagName - Component tag name
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function preloadComponent(tagName) {
|
||||
if (!COMPONENT_REGISTRY[tagName]) {
|
||||
throw new Error(`Component not found in registry: ${tagName}`);
|
||||
}
|
||||
|
||||
if (!loadedComponents.has(tagName)) {
|
||||
await COMPONENT_REGISTRY[tagName]();
|
||||
loadedComponents.add(tagName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload multiple components in parallel
|
||||
* @param {Array<string>} tagNames - Array of component tag names
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function preloadComponents(tagNames) {
|
||||
await Promise.all(
|
||||
tagNames.map(tag => preloadComponent(tag).catch(err => {
|
||||
console.warn(`Failed to preload ${tag}:`, err);
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get registry statistics
|
||||
* @returns {object} Stats about loaded/unloaded components
|
||||
*/
|
||||
export function getRegistryStats() {
|
||||
const total = Object.keys(COMPONENT_REGISTRY).length;
|
||||
const loaded = loadedComponents.size;
|
||||
|
||||
return {
|
||||
total,
|
||||
loaded,
|
||||
unloaded: total - loaded,
|
||||
loadedComponents: Array.from(loadedComponents),
|
||||
availableComponents: Object.keys(COMPONENT_REGISTRY)
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user