feat: Complete HTML-first architecture implementation with API integration
- Replace value field with html_content for direct HTML storage - Add original_template field for style detection preservation - Remove all markdown processing from injector (delete markdown.go) - Fix critical content extraction/injection bugs in engine - Add missing UpdateContent PUT handler for content persistence - Fix API client field names and add updateContent() method - Resolve content type validation (only allow text/link types) - Add UUID-based ID generation to prevent collisions - Complete first-pass processing workflow for unprocessed elements - Verify end-to-end: Enhancement → Database → API → Editor → Persistence All 37 files updated for HTML-first content management system. Phase 3a implementation complete and production ready.
This commit is contained in:
@@ -33,7 +33,7 @@ export class ApiClient {
|
||||
try {
|
||||
const payload = {
|
||||
html_markup: htmlMarkup, // Always send HTML markup - server extracts ID or generates new one
|
||||
value: content,
|
||||
html_content: content,
|
||||
type: type,
|
||||
file_path: this.getCurrentFilePath() // Always include file path for consistent ID generation
|
||||
};
|
||||
@@ -66,6 +66,40 @@ export class ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
async updateContent(contentId, content) {
|
||||
try {
|
||||
const payload = {
|
||||
html_content: content
|
||||
};
|
||||
|
||||
const response = await fetch(`${this.baseUrl}/${contentId}?site_id=${this.siteId}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${this.getAuthToken()}`
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
console.log(`✅ Content updated: ${contentId}`);
|
||||
return result;
|
||||
} else {
|
||||
console.warn(`⚠️ Update failed (${response.status}): ${contentId}`);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.name === 'TypeError' && error.message.includes('fetch')) {
|
||||
console.warn(`🔌 API Server not reachable at ${this.baseUrl}`);
|
||||
console.warn('💡 Start full-stack development: just dev');
|
||||
} else {
|
||||
console.error('Failed to update content:', contentId, error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async getContentVersions(contentId) {
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/${contentId}/versions?site_id=${this.siteId}`);
|
||||
|
||||
@@ -134,24 +134,13 @@ export class InsertrCore {
|
||||
detectContentType(element) {
|
||||
const tag = element.tagName.toLowerCase();
|
||||
|
||||
if (element.classList.contains('insertr-group')) {
|
||||
return 'group';
|
||||
// Only return database-valid types: 'text' or 'link'
|
||||
if (tag === 'a' || tag === 'button') {
|
||||
return 'link';
|
||||
}
|
||||
|
||||
switch (tag) {
|
||||
case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6':
|
||||
return 'text';
|
||||
case 'p':
|
||||
return 'textarea';
|
||||
case 'a': case 'button':
|
||||
return 'link';
|
||||
case 'div': case 'section':
|
||||
return 'text';
|
||||
case 'span':
|
||||
return 'text';
|
||||
default:
|
||||
return 'text';
|
||||
}
|
||||
// All other elements are text content
|
||||
return 'text';
|
||||
}
|
||||
|
||||
// Get all elements with their metadata, including group elements
|
||||
|
||||
Reference in New Issue
Block a user