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:
233
admin-ui/js/components/tools/ds-esre-editor.js
Normal file
233
admin-ui/js/components/tools/ds-esre-editor.js
Normal file
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* ds-esre-editor.js
|
||||
* Editor for ESRE (Explicit Style Requirements and Expectations)
|
||||
* QA Team Tool #2
|
||||
*/
|
||||
|
||||
import { createEditorView, setupEditorHandlers } from '../../utils/tool-templates.js';
|
||||
import { ComponentHelpers } from '../../utils/component-helpers.js';
|
||||
import contextStore from '../../stores/context-store.js';
|
||||
|
||||
class DSESREEditor extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.esreContent = '';
|
||||
this.isSaving = false;
|
||||
}
|
||||
|
||||
async connectedCallback() {
|
||||
this.render();
|
||||
await this.loadESRE();
|
||||
}
|
||||
|
||||
async loadESRE() {
|
||||
try {
|
||||
const context = contextStore.getMCPContext();
|
||||
if (!context.project_id) {
|
||||
throw new Error('No project selected');
|
||||
}
|
||||
|
||||
// Load ESRE from project configuration
|
||||
const response = await fetch(`/api/projects/${context.project_id}/esre`);
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
this.esreContent = result.content || '';
|
||||
this.renderEditor();
|
||||
} else {
|
||||
// No ESRE yet, start with template
|
||||
this.esreContent = this.getESRETemplate();
|
||||
this.renderEditor();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[DSESREEditor] Failed to load ESRE:', error);
|
||||
this.esreContent = this.getESRETemplate();
|
||||
this.renderEditor();
|
||||
}
|
||||
}
|
||||
|
||||
getESRETemplate() {
|
||||
return `# Explicit Style Requirements and Expectations (ESRE)
|
||||
|
||||
## Project: ${contextStore.get('projectId') || 'Design System'}
|
||||
|
||||
### Color Requirements
|
||||
- Primary colors must match Figma specifications exactly
|
||||
- Accessibility: All text must meet WCAG 2.1 AA contrast ratios
|
||||
- Color tokens must be used instead of hardcoded hex values
|
||||
|
||||
### Typography Requirements
|
||||
- Font families: [Specify approved fonts]
|
||||
- Font sizes must use design system scale
|
||||
- Line heights must maintain readability
|
||||
- Letter spacing should follow design specifications
|
||||
|
||||
### Spacing Requirements
|
||||
- All spacing must use design system spacing scale
|
||||
- Margins and padding should be consistent across components
|
||||
- Grid system: [Specify grid specifications]
|
||||
|
||||
### Component Requirements
|
||||
- All components must be built from design system primitives
|
||||
- Component variants must match Figma component variants
|
||||
- Props should follow naming conventions
|
||||
|
||||
### Responsive Requirements
|
||||
- Breakpoints: [Specify breakpoints]
|
||||
- Mobile-first approach required
|
||||
- Touch targets must be at least 44x44px
|
||||
|
||||
### Accessibility Requirements
|
||||
- All interactive elements must be keyboard accessible
|
||||
- ARIA labels required for icon-only buttons
|
||||
- Focus indicators must be visible
|
||||
- Screen reader testing required
|
||||
|
||||
### Performance Requirements
|
||||
- Initial load time: [Specify target]
|
||||
- Time to Interactive: [Specify target]
|
||||
- Bundle size limits: [Specify limits]
|
||||
|
||||
### Browser Support
|
||||
- Chrome: Latest 2 versions
|
||||
- Firefox: Latest 2 versions
|
||||
- Safari: Latest 2 versions
|
||||
- Edge: Latest 2 versions
|
||||
|
||||
---
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
### Pre-Deployment
|
||||
- [ ] All colors match Figma specifications
|
||||
- [ ] Typography follows design system scale
|
||||
- [ ] Spacing uses design tokens
|
||||
- [ ] Components match design system library
|
||||
- [ ] Responsive behavior validated
|
||||
- [ ] Accessibility audit passed
|
||||
- [ ] Performance metrics met
|
||||
- [ ] Cross-browser testing completed
|
||||
|
||||
### QA Testing
|
||||
- [ ] Visual comparison with Figma
|
||||
- [ ] Keyboard navigation tested
|
||||
- [ ] Screen reader compatibility verified
|
||||
- [ ] Mobile devices tested
|
||||
- [ ] Edge cases validated
|
||||
|
||||
---
|
||||
|
||||
Last updated: ${new Date().toISOString().split('T')[0]}
|
||||
`;
|
||||
}
|
||||
|
||||
renderEditor() {
|
||||
const container = this.querySelector('#editor-container');
|
||||
if (!container) return;
|
||||
|
||||
const config = {
|
||||
title: 'ESRE Editor',
|
||||
content: this.esreContent,
|
||||
language: 'markdown',
|
||||
onSave: (content) => this.saveESRE(content),
|
||||
onExport: (content) => this.exportESRE(content)
|
||||
};
|
||||
|
||||
container.innerHTML = createEditorView(config);
|
||||
setupEditorHandlers(container, config);
|
||||
}
|
||||
|
||||
async saveESRE(content) {
|
||||
this.isSaving = true;
|
||||
const saveBtn = document.querySelector('#editor-save-btn');
|
||||
if (saveBtn) {
|
||||
saveBtn.disabled = true;
|
||||
saveBtn.textContent = '⏳ Saving...';
|
||||
}
|
||||
|
||||
try {
|
||||
const context = contextStore.getMCPContext();
|
||||
if (!context.project_id) {
|
||||
throw new Error('No project selected');
|
||||
}
|
||||
|
||||
// Save ESRE via API
|
||||
const response = await fetch('/api/esre/save', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
projectId: context.project_id,
|
||||
content
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Save failed: ${response.statusText}`);
|
||||
}
|
||||
|
||||
this.esreContent = content;
|
||||
ComponentHelpers.showToast?.('ESRE saved successfully', 'success');
|
||||
} catch (error) {
|
||||
console.error('[DSESREEditor] Save failed:', error);
|
||||
ComponentHelpers.showToast?.(`Save failed: ${error.message}`, 'error');
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
if (saveBtn) {
|
||||
saveBtn.disabled = false;
|
||||
saveBtn.textContent = '💾 Save';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exportESRE(content) {
|
||||
const blob = new Blob([content], { type: 'text/markdown' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
const projectId = contextStore.get('projectId') || 'project';
|
||||
a.href = url;
|
||||
a.download = `${projectId}-esre.md`;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
ComponentHelpers.showToast?.('ESRE exported', 'success');
|
||||
}
|
||||
|
||||
render() {
|
||||
this.innerHTML = `
|
||||
<div style="display: flex; flex-direction: column; height: 100%;">
|
||||
<!-- Info Banner -->
|
||||
<div style="padding: 12px 16px; background: rgba(255, 191, 0, 0.1); border-bottom: 1px solid var(--vscode-border);">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<div style="font-size: 20px;">📋</div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-size: 11px; font-weight: 600; margin-bottom: 2px;">
|
||||
ESRE: Explicit Style Requirements and Expectations
|
||||
</div>
|
||||
<div style="font-size: 10px; color: var(--vscode-text-dim);">
|
||||
Define clear specifications for design implementation and QA validation
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Editor Container -->
|
||||
<div id="editor-container" style="flex: 1; overflow: hidden;">
|
||||
${createEditorView({
|
||||
title: 'ESRE Editor',
|
||||
content: this.esreContent,
|
||||
language: 'markdown',
|
||||
onSave: (content) => this.saveESRE(content),
|
||||
onExport: (content) => this.exportESRE(content)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<!-- Help Footer -->
|
||||
<div style="padding: 8px 16px; border-top: 1px solid var(--vscode-border); font-size: 10px; color: var(--vscode-text-dim);">
|
||||
💡 Tip: Use Markdown formatting for clear documentation. Save changes before closing.
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('ds-esre-editor', DSESREEditor);
|
||||
|
||||
export default DSESREEditor;
|
||||
Reference in New Issue
Block a user