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)
|
||||
};
|
||||
}
|
||||
169
admin-ui/js/config/panel-config.js
Normal file
169
admin-ui/js/config/panel-config.js
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* panel-config.js
|
||||
* Central registry for team-specific panel configurations
|
||||
*/
|
||||
|
||||
export const PANEL_CONFIGS = {
|
||||
ui: [
|
||||
{
|
||||
id: 'metrics',
|
||||
label: 'Metrics',
|
||||
component: 'ds-metrics-panel',
|
||||
props: { mode: 'ui-performance' }
|
||||
},
|
||||
{
|
||||
id: 'tokens',
|
||||
label: 'Token Inspector',
|
||||
component: 'ds-token-inspector',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'figma',
|
||||
label: 'Figma Sync',
|
||||
component: 'ds-figma-status',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'activity',
|
||||
label: 'Activity',
|
||||
component: 'ds-activity-log',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'chat',
|
||||
label: 'AI Assistant',
|
||||
component: 'ds-chat-panel',
|
||||
props: {}
|
||||
}
|
||||
],
|
||||
|
||||
ux: [
|
||||
{
|
||||
id: 'metrics',
|
||||
label: 'Metrics',
|
||||
component: 'ds-metrics-panel',
|
||||
props: { mode: 'ux-accessibility' }
|
||||
},
|
||||
{
|
||||
id: 'diff',
|
||||
label: 'Visual Diff',
|
||||
component: 'ds-visual-diff',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'accessibility',
|
||||
label: 'Accessibility',
|
||||
component: 'ds-accessibility-report',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'screenshots',
|
||||
label: 'Screenshots',
|
||||
component: 'ds-screenshot-gallery',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'chat',
|
||||
label: 'AI Assistant',
|
||||
component: 'ds-chat-panel',
|
||||
props: {}
|
||||
}
|
||||
],
|
||||
|
||||
qa: [
|
||||
{
|
||||
id: 'metrics',
|
||||
label: 'Metrics',
|
||||
component: 'ds-metrics-panel',
|
||||
props: { mode: 'qa-coverage' }
|
||||
},
|
||||
{
|
||||
id: 'console',
|
||||
label: 'Console',
|
||||
component: 'ds-console-viewer',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'network',
|
||||
label: 'Network',
|
||||
component: 'ds-network-monitor',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'tests',
|
||||
label: 'Test Results',
|
||||
component: 'ds-test-results',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'chat',
|
||||
label: 'AI Assistant',
|
||||
component: 'ds-chat-panel',
|
||||
props: {}
|
||||
}
|
||||
],
|
||||
|
||||
// Admin uses full-page layout, minimal bottom panel
|
||||
admin: [
|
||||
{
|
||||
id: 'system',
|
||||
label: 'System Log',
|
||||
component: 'ds-system-log',
|
||||
props: {}
|
||||
},
|
||||
{
|
||||
id: 'chat',
|
||||
label: 'AI Assistant',
|
||||
component: 'ds-chat-panel',
|
||||
props: {}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Advanced mode adds Console and Network tabs to any workflow
|
||||
*/
|
||||
export const ADVANCED_MODE_TABS = [
|
||||
{
|
||||
id: 'console',
|
||||
label: 'Console',
|
||||
component: 'ds-console-viewer',
|
||||
props: {},
|
||||
advanced: true
|
||||
},
|
||||
{
|
||||
id: 'network',
|
||||
label: 'Network',
|
||||
component: 'ds-network-monitor',
|
||||
props: {},
|
||||
advanced: true
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* Get panel configuration for a team
|
||||
* @param {string} teamId - Team identifier (ui, ux, qa, admin)
|
||||
* @param {boolean} advancedMode - Whether advanced mode is enabled
|
||||
* @returns {Array} Panel configuration
|
||||
*/
|
||||
export function getPanelConfig(teamId, advancedMode = false) {
|
||||
const baseConfig = PANEL_CONFIGS[teamId] || PANEL_CONFIGS.ui;
|
||||
|
||||
if (!advancedMode) {
|
||||
return baseConfig;
|
||||
}
|
||||
|
||||
// In advanced mode, add Console/Network if not already present
|
||||
const hasConsole = baseConfig.some(tab => tab.id === 'console');
|
||||
const hasNetwork = baseConfig.some(tab => tab.id === 'network');
|
||||
|
||||
const advancedTabs = [];
|
||||
if (!hasConsole) {
|
||||
advancedTabs.push(ADVANCED_MODE_TABS[0]);
|
||||
}
|
||||
if (!hasNetwork) {
|
||||
advancedTabs.push(ADVANCED_MODE_TABS[1]);
|
||||
}
|
||||
|
||||
return [...baseConfig, ...advancedTabs];
|
||||
}
|
||||
Reference in New Issue
Block a user