Compare commits

...

8 Commits

Author SHA1 Message Date
3334937b67 2.3.35
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 9s
Build & Deploy / 🧪 QA (push) Successful in 1m13s
Build & Deploy / 🏗️ Build (push) Successful in 2m22s
Build & Deploy / 🚀 Deploy (push) Successful in 16s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m18s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-08-07 17:51:12 +02:00
246e6540d4 fix(products): remove malformed payload AST brace artifact from markdown 2026-08-07 17:51:11 +02:00
aa299b285d 2.3.34
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 10s
Build & Deploy / 🧪 QA (push) Successful in 1m12s
Build & Deploy / 🏗️ Build (push) Successful in 2m14s
Build & Deploy / 🚀 Deploy (push) Successful in 16s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m16s
Build & Deploy / 🔔 Notify (push) Successful in 3s
2026-08-07 17:20:21 +02:00
2be0d1ea92 chore(products): migrate payload CMS lexical AST into permanent markdown
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 11s
Build & Deploy / 🧪 QA (push) Successful in 1m10s
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🏗️ Build (push) Has been cancelled
2026-08-07 17:18:02 +02:00
0554460153 fix(products): extract lexical AST and JSON-LD data correctly from productTabs block
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 10s
Build & Deploy / 🧪 QA (push) Failing after 52s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-08-07 17:12:55 +02:00
4ae45b1aa7 chore(release): 2.3.33 - NA Kabel Leiterklassen Fix
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 9s
Build & Deploy / 🧪 QA (push) Successful in 1m11s
Build & Deploy / 🏗️ Build (push) Successful in 2m15s
Build & Deploy / 🚀 Deploy (push) Successful in 16s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m1s
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-08-07 16:16:25 +02:00
76cbdaa37e fix: remove class 1 conductor shapes (RE, SE) from all NA cables
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 9s
Build & Deploy / 🏗️ Build (push) Has been cancelled
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🧪 QA (push) Has been cancelled
2026-08-07 14:49:27 +02:00
5b1a2eff7f fix(mdx): handle productTabs in MDXContent to resolve Unknown Block Type
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 9s
Build & Deploy / 🧪 QA (push) Successful in 1m13s
Build & Deploy / 🏗️ Build (push) Successful in 2m15s
Build & Deploy / 🚀 Deploy (push) Successful in 16s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m22s
Build & Deploy / 🔔 Notify (push) Successful in 3s
2026-08-07 12:54:02 +02:00
32 changed files with 1066 additions and 564 deletions

1
.gitignore vendored
View File

@@ -28,3 +28,4 @@ backups/
# Local data / backups
.data/
scratch/

View File

@@ -266,18 +266,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
notFound();
}
let technicalItems = [];
try {
const tabMatch =
typeof product.content === 'string' &&
product.content.match(/<Block type="productTabs" data={({.*?})}\s*\/>/s);
if (tabMatch && tabMatch[1]) {
const data = JSON.parse(tabMatch[1]);
technicalItems = data.technicalItems || [];
}
} catch (e) {
// Ignore JSON parse errors for AST
}
let technicalItems: any[] = [];
const datasheetPath = getDatasheetPath(productSlug, locale);
const isFallback = (product.frontmatter as any).isFallback;
@@ -296,8 +285,20 @@ export default async function ProductPage({ params }: ProductPageProps) {
if (typeof product.content === 'string') {
const tabBlockMatch = product.content.match(/<Block type="productTabs".*?\/>/s);
if (tabBlockMatch) {
descriptionContent = product.content.replace(tabBlockMatch[0], '');
technicalContent = tabBlockMatch[0];
descriptionContent = product.content.replace(tabBlockMatch[0], '');
const dataMatch =
technicalContent.match(/data="({.*?})"/s) || technicalContent.match(/data={({.*?})}/s);
if (dataMatch && dataMatch[1]) {
try {
const rawJsonStr = dataMatch[1].replace(/&quot;/g, '"');
const data = JSON.parse(rawJsonStr);
technicalItems = data.technicalItems || [];
} catch (e) {
console.error('Failed to parse productTabs data for page:', e);
}
}
}
}

View File

@@ -24,6 +24,7 @@ import VideoSection from './home/VideoSection';
import CTA from './home/CTA';
import { AgbHistoryBlock } from './AgbHistoryBlock';
import { PDFDownloadBlock } from './PDFDownloadBlock';
import ProductTechnicalData from './ProductTechnicalData';
function ContactSection(props: any) {
return (
<div className="p-8 border-2 border-dashed border-primary my-8 text-center text-primary font-bold">
@@ -100,6 +101,8 @@ async function Block(props: any) {
return <AgbHistoryBlock {...data} />;
case 'pdfDownload':
return <PDFDownloadBlock {...data} />;
case 'productTabs':
return <ProductTechnicalData data={data} />;
default:
return (

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -66,3 +66,81 @@ export function fixMdxDataProps(content: string): string {
return fixedContent;
}
export function lexicalToMarkdown(node: any, depth = 0): string {
if (!node) return '';
if (typeof node === 'string') return node;
if (node.type === 'text') {
let text = node.text || '';
if (node.format === 1) text = `**${text}**`; // Bold
if (node.format === 2) text = `*${text}*`; // Italic
return text;
}
if (node.type === 'heading') {
const level = parseInt((node.tag || 'h1').replace('h', '')) || 1;
const prefix = '#'.repeat(level);
const text = (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
return `${prefix} ${text}\n\n`;
}
if (node.type === 'paragraph') {
const text = (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
return text.trim() ? `${text}\n\n` : '\n';
}
if (node.type === 'list') {
const isOrdered = node.tag === 'ol';
const items = (node.children || [])
.map((c: any, index: number) => {
const prefix = isOrdered ? `${index + 1}.` : '-';
return `${prefix} ${lexicalToMarkdown(c, depth + 1).trim()}`;
})
.join('\n');
return `${items}\n\n`;
}
if (node.type === 'listitem') {
return (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
}
if (node.type === 'quote') {
const text = (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
return `> ${text}\n\n`;
}
if (node.type === 'link') {
const url = node.fields?.url || node.url || '';
const text = (node.children || []).map((c: any) => lexicalToMarkdown(c, depth)).join('');
return `[${text}](${url})`;
}
if (node.type === 'upload') {
const url = node.value?.url || '';
const alt = node.value?.alt || node.value?.filename || '';
return `![${alt}](${url})\n\n`;
}
if (node.type === 'block') {
const blockType = node.fields?.blockType;
if (blockType === 'contactSection') {
return `<ContactSection showMap={${!!node.fields?.showMap}} showForm={${!!node.fields?.showForm}} showHours={${!!node.fields?.showHours}} />\n\n`;
}
if (blockType === 'heroSection') {
return `<HeroSection badge="${node.fields?.badge || ''}" title="${node.fields?.title || ''}" subtitle="${node.fields?.subtitle || ''}" alignment="${node.fields?.alignment || 'left'}" />\n\n`;
}
if (blockType === 'features') {
return `<FeaturesSection layout="${node.fields?.layout || ''}" />\n\n`;
}
// Generic MDX block wrapper if unknown
return `<Block type="${blockType}" data={${JSON.stringify(node.fields)}} />\n\n`;
}
if (node.children && Array.isArray(node.children)) {
return node.children.map((c: any) => lexicalToMarkdown(c, depth)).join('');
}
return '';
}

View File

@@ -116,7 +116,7 @@
"prepare": "husky",
"preinstall": "npx only-allow pnpm"
},
"version": "2.3.32",
"version": "2.3.35",
"pnpm": {
"onlyBuiltDependencies": [
"@parcel/watcher",

27
tests/lexical.test.ts Normal file
View File

@@ -0,0 +1,27 @@
import { describe, it, expect } from 'vitest';
import { lexicalToMarkdown } from '../lib/mdx-utils';
describe('lexicalToMarkdown', () => {
it('should convert lexical AST to markdown', () => {
const ast = {
type: 'root',
children: [
{
type: 'paragraph',
children: [
{ type: 'text', text: 'Hello ' },
{ type: 'text', text: 'World', format: 1 }, // bold
],
},
{
type: 'heading',
tag: 'h2',
children: [{ type: 'text', text: 'Title' }],
},
],
};
const result = lexicalToMarkdown(ast);
expect(result).toBe('Hello **World**\n\n## Title\n\n');
});
});

View File

@@ -0,0 +1,14 @@
import { describe, it, expect } from 'vitest';
import * as fs from 'fs';
import * as path from 'path';
describe('MDXContent Mapping', () => {
it('should have productTabs in the switch statement to prevent Unknown Block Type errors', () => {
const filePath = path.join(process.cwd(), 'components/MDXContent.tsx');
const fileContent = fs.readFileSync(filePath, 'utf-8');
// Check if the switch case for productTabs exists
expect(fileContent).toContain("case 'productTabs':");
expect(fileContent).toContain('<ProductTechnicalData');
});
});