Files
dss/admin-ui/js/core/component-config.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

273 lines
6.8 KiB
JavaScript

/**
* Component Configuration Registry
*
* Extensible registry for external tools and components.
* Each component defines its config schema, making it easy to:
* - Add new tools without code changes
* - Generate settings UI dynamically
* - Validate configurations
* - Store and retrieve settings consistently
*/
import { getConfig, getDssHost, getStorybookPort } from './config-loader.js';
/**
* Component Registry
* Add new components here to extend the settings system.
*/
export const componentRegistry = {
storybook: {
id: 'storybook',
name: 'Storybook',
description: 'Component documentation and playground',
icon: 'book',
category: 'documentation',
// Config schema - defines available settings
config: {
port: {
type: 'number',
label: 'Port',
default: 6006,
readonly: true, // Derived from server config
description: 'Storybook runs on this port',
},
theme: {
type: 'select',
label: 'Theme',
options: [
{ value: 'light', label: 'Light' },
{ value: 'dark', label: 'Dark' },
{ value: 'auto', label: 'Auto (System)' },
],
default: 'auto',
description: 'Storybook UI theme preference',
},
showDocs: {
type: 'boolean',
label: 'Show Docs Tab',
default: true,
description: 'Display the documentation tab in stories',
},
},
// Dynamic URL builder (uses nginx path-based routing)
getUrl() {
try {
const host = getDssHost();
const protocol = window.location.protocol;
// Admin configured path-based routing at /storybook/
return `${protocol}//${host}/storybook/`;
} catch {
return null;
}
},
// Status check
async checkStatus() {
const url = this.getUrl();
if (!url) return { status: 'unknown', message: 'Configuration not loaded' };
try {
const response = await fetch(url, { mode: 'no-cors', cache: 'no-cache' });
return { status: 'available', message: 'Storybook is running' };
} catch {
return { status: 'unavailable', message: 'Storybook is not responding' };
}
},
},
figma: {
id: 'figma',
name: 'Figma',
description: 'Design file integration and token extraction',
icon: 'figma',
category: 'design',
config: {
apiKey: {
type: 'password',
label: 'API Token',
placeholder: 'figd_xxxxxxxxxx',
description: 'Your Figma Personal Access Token',
sensitive: true, // Never display actual value
},
fileKey: {
type: 'text',
label: 'Default File Key',
placeholder: 'Enter Figma file key',
description: 'Default Figma file to use for token extraction',
},
autoSync: {
type: 'boolean',
label: 'Auto-sync Tokens',
default: false,
description: 'Automatically sync tokens when file changes detected',
},
},
getUrl() {
return 'https://www.figma.com';
},
async checkStatus() {
// Check if API key is configured via backend
try {
const response = await fetch('/api/figma/health');
const data = await response.json();
if (data.configured) {
return { status: 'connected', message: `Connected as ${data.user || 'user'}` };
}
return { status: 'not_configured', message: 'API token not set' };
} catch {
return { status: 'error', message: 'Failed to check Figma status' };
}
},
},
// Future components can be added here
jira: {
id: 'jira',
name: 'Jira',
description: 'Issue tracking integration',
icon: 'clipboard',
category: 'project',
enabled: false, // Not yet implemented
config: {
baseUrl: {
type: 'url',
label: 'Jira URL',
placeholder: 'https://your-org.atlassian.net',
description: 'Your Jira instance URL',
},
projectKey: {
type: 'text',
label: 'Project Key',
placeholder: 'DS',
description: 'Default Jira project key',
},
},
getUrl() {
return localStorage.getItem('jira_base_url') || null;
},
async checkStatus() {
return { status: 'not_implemented', message: 'Coming soon' };
},
},
confluence: {
id: 'confluence',
name: 'Confluence',
description: 'Documentation wiki integration',
icon: 'file-text',
category: 'documentation',
enabled: false, // Not yet implemented
config: {
baseUrl: {
type: 'url',
label: 'Confluence URL',
placeholder: 'https://your-org.atlassian.net/wiki',
description: 'Your Confluence instance URL',
},
spaceKey: {
type: 'text',
label: 'Space Key',
placeholder: 'DS',
description: 'Default Confluence space key',
},
},
getUrl() {
return localStorage.getItem('confluence_base_url') || null;
},
async checkStatus() {
return { status: 'not_implemented', message: 'Coming soon' };
},
},
};
/**
* Get all enabled components
*/
export function getEnabledComponents() {
return Object.values(componentRegistry).filter(c => c.enabled !== false);
}
/**
* Get components by category
*/
export function getComponentsByCategory(category) {
return Object.values(componentRegistry).filter(c => c.category === category && c.enabled !== false);
}
/**
* Get component by ID
*/
export function getComponent(id) {
return componentRegistry[id] || null;
}
/**
* Get component setting value
*/
export function getComponentSetting(componentId, settingKey) {
const storageKey = `dss_component_${componentId}_${settingKey}`;
const stored = localStorage.getItem(storageKey);
if (stored !== null) {
try {
return JSON.parse(stored);
} catch {
return stored;
}
}
// Return default value from schema
const component = getComponent(componentId);
if (component && component.config[settingKey]) {
const defaultValue = component.config[settingKey].default;
if (defaultValue !== undefined) {
return defaultValue;
}
}
return null;
}
/**
* Set component setting value
*/
export function setComponentSetting(componentId, settingKey, value) {
const storageKey = `dss_component_${componentId}_${settingKey}`;
localStorage.setItem(storageKey, JSON.stringify(value));
}
/**
* Get all settings for a component
*/
export function getComponentSettings(componentId) {
const component = getComponent(componentId);
if (!component) return {};
const settings = {};
for (const key of Object.keys(component.config)) {
settings[key] = getComponentSetting(componentId, key);
}
return settings;
}
export default {
componentRegistry,
getEnabledComponents,
getComponentsByCategory,
getComponent,
getComponentSetting,
setComponentSetting,
getComponentSettings,
};