This commit is contained in:
2026-01-30 00:17:46 +01:00
parent 51565fdf41
commit 14b2f83971
121 changed files with 121 additions and 43 deletions

View File

@@ -191,7 +191,12 @@ async function loadProductsFromExcelAndMdx(locale: 'en' | 'de'): Promise<Product
locale,
categories: (mdx?.categories || []).map(name => ({ name })),
attributes: [],
voltageType: data.voltageType,
voltageType: (() => {
const cats = (mdx?.categories || []).map(c => String(c));
const isMV = cats.some(c => /medium[-\s]?voltage|mittelspannung/i.test(c));
if (isMV && data.voltageType === 'high-voltage') return 'medium-voltage';
return data.voltageType;
})(),
});
});

View File

@@ -177,6 +177,10 @@ function technicalFullLabel(args: { key: string; excelKey: string; locale: 'en'
case 'out_temp_fixed': return 'Zul. Kabelaußentemperatur, fest verlegt';
case 'out_temp_motion': return 'Zul. Kabelaußentemperatur, in Bewegung';
case 'max_sc_temp_val': return 'Maximale Kurzschlußtemperatur';
case 'max_sc_temp': return 'Maximale Kurzschlußtemperatur';
case 'max_op_temp': return 'Max. zulässige Leitertemperatur';
case 'min_store_temp': return 'Minimale Lagertemperatur';
case 'min_lay_temp': return 'Mindesttemperatur Verlegung';
case 'min_bend_fixed': return 'Min. Biegeradius, fest verlegt';
case 'min_lay_temp_val': return 'Mindesttemperatur Verlegung';
case 'meter_mark': return 'Metermarkierung';
@@ -195,6 +199,16 @@ function technicalFullLabel(args: { key: string; excelKey: string; locale: 'en'
case 'flame': return 'Flammhemmend';
case 'G': return 'Gewicht';
case 'Fzv': return 'Zugkraft';
case 'DI': return 'Durchmesser über Isolation';
case 'Ik_cond': return 'Kurzschlussstrom Leiter';
case 'Ik_screen': return 'Kurzschlussstrom Schirm';
case 'D_screen': return 'Durchmesser über Schirm';
case 'S_screen': return 'Metallischer Schirm';
case 'cross_section': return 'Querschnitt';
case 'shape': return 'Leiterform';
case 'Ibl': return 'Strombelastbarkeit (Luft)';
case 'Ibe': return 'Strombelastbarkeit (Erde)';
case 'Cond': return 'Leitermaterial';
}
} else {
switch (key) {
@@ -213,6 +227,10 @@ function technicalFullLabel(args: { key: string; excelKey: string; locale: 'en'
case 'out_temp_fixed': return 'Permissible cable outer temperature, fixed';
case 'out_temp_motion': return 'Permissible cable outer temperature, in motion';
case 'max_sc_temp_val': return 'Maximum short-circuit temperature';
case 'max_sc_temp': return 'Maximum short-circuit temperature';
case 'max_op_temp': return 'Max. permissible conductor temperature';
case 'min_store_temp': return 'Minimum storage temperature';
case 'min_lay_temp': return 'Minimum laying temperature';
case 'min_bend_fixed': return 'Min. bending radius, fixed';
case 'min_lay_temp_val': return 'Minimum laying temperature';
case 'meter_mark': return 'Meter marking';
@@ -231,6 +249,16 @@ function technicalFullLabel(args: { key: string; excelKey: string; locale: 'en'
case 'flame': return 'Flame retardant';
case 'G': return 'Weight';
case 'Fzv': return 'Pulling force';
case 'DI': return 'Diameter over insulation';
case 'Ik_cond': return 'Short-circuit current conductor';
case 'Ik_screen': return 'Short-circuit current screen';
case 'D_screen': return 'Diameter over screen';
case 'S_screen': return 'Metallic screen';
case 'cross_section': return 'Cross-section';
case 'shape': return 'Conductor shape';
case 'Ibl': return 'Current rating (air)';
case 'Ibe': return 'Current rating (ground)';
case 'Cond': return 'Conductor material';
}
}
@@ -285,33 +313,37 @@ function technicalValueTranslation(args: { label: string; value: string; locale:
.replace(/\bXLPE\b/gi, 'VPE');
}
if (/^ja$/i.test(v)) return 'yes';
if (/^nein$/i.test(v)) return 'no';
if (/^kupfer$/i.test(v)) return 'Copper';
if (/^aluminium$/i.test(v)) return 'Aluminum';
if (/^schwarz$/i.test(v)) return 'black';
if (/^mehrdrähtig$/i.test(v)) return 'stranded';
if (/^(\d+)xD$/i.test(v)) return v.replace(/^(\d+)xD$/i, '$1 times diameter');
if (/^VPE/i.test(v)) return v.replace(/^VPE/i, 'XLPE');
if (/^ja, mit Quellvliess$/i.test(v)) return 'yes, with swelling tape';
if (/^ja, Al-Band$/i.test(v)) return 'yes, Al-tape';
if (/^Polyethylen/i.test(v)) return v.replace(/^Polyethylen/i, 'Polyethylene');
if (/^Klasse 2 mehrdrähtig$/i.test(v)) return 'Class 2 stranded';
if (/^innere und äußere Leitschicht aus halbleitendem Kunststoff - 3-fach-extrudiert$/i.test(v)) return 'inner and outer semiconducting layer made of semiconducting plastic - 3-fold extruded';
if (/^Kupferdrähte \+ Querleitwendel$/i.test(v)) return 'copper wires + transverse conductive helix';
if (/^Polyethylen DMP2$/i.test(v)) return 'Polyethylene DMP2';
if (/^15 facher Durchmesser$/i.test(v)) return '15 times diameter';
// Fallback for partial matches or common terms
return v
.replace(/\bkupfer\b/gi, 'Copper')
.replace(/\baluminium\b/gi, 'Aluminum')
.replace(/\bschwarz\b/gi, 'black')
.replace(/\bmehrdrähtig\b/gi, 'stranded')
.replace(/\bja\b/gi, 'yes')
.replace(/\bnein\b/gi, 'no')
.replace(/\bPolyethylen\b/gi, 'Polyethylene')
.replace(/\bVPE\b/gi, 'XLPE');
if (args.locale === 'en') {
if (/^ja$/i.test(v)) return 'yes';
if (/^nein$/i.test(v)) return 'no';
if (/^kupfer$/i.test(v)) return 'Copper';
if (/^aluminium$/i.test(v)) return 'Aluminum';
if (/^schwarz$/i.test(v)) return 'black';
if (/^mehrdrähtig$/i.test(v)) return 'stranded';
if (/^(\d+)xD$/i.test(v)) return v.replace(/^(\d+)xD$/i, '$1 times diameter');
if (/^VPE/i.test(v)) return v.replace(/^VPE/i, 'XLPE');
if (/^ja, mit Quellvliess$/i.test(v)) return 'yes, with swelling tape';
if (/^ja, Al-Band$/i.test(v)) return 'yes, Al-tape';
if (/^Polyethylen/i.test(v)) return v.replace(/^Polyethylen/i, 'Polyethylene');
if (/^Klasse 2 mehrdrähtig$/i.test(v)) return 'Class 2 stranded';
if (/^innere und äußere Leitschicht aus halbleitendem Kunststoff - 3-fach-extrudiert$/i.test(v)) return 'inner and outer semiconducting layer made of semiconducting plastic - 3-fold extruded';
if (/^Kupferdrähte \+ Querleitwendel$/i.test(v)) return 'copper wires + transverse conductive helix';
if (/^Polyethylen DMP2$/i.test(v)) return 'Polyethylene DMP2';
if (/^15 facher Durchmesser$/i.test(v)) return '15 times diameter';
// Fallback for partial matches or common terms
return v
.replace(/\bkupfer\b/gi, 'Copper')
.replace(/\baluminium\b/gi, 'Aluminum')
.replace(/\bschwarz\b/gi, 'black')
.replace(/\bmehrdrähtig\b/gi, 'stranded')
.replace(/\bja\b/gi, 'yes')
.replace(/\bnein\b/gi, 'no')
.replace(/\bPolyethylen\b/gi, 'Polyethylene')
.replace(/\bVPE\b/gi, 'XLPE');
}
return v;
}
function metaFullLabel(args: { key: string; excelKey: string; locale: 'en' | 'de' }): string {
@@ -334,6 +366,26 @@ function metaFullLabel(args: { key: string; excelKey: string; locale: 'en' | 'de
return 'CPR-Klasse';
case 'flame':
return 'Flammhemmend';
case 'DI': return 'Durchmesser über Isolation';
case 'RI': return 'DC-Leiterwiderstand (20 °C)';
case 'Wi': return 'Isolationsdicke';
case 'Wm': return 'Manteldicke';
case 'Rbv': return 'Biegeradius';
case 'Fzv': return 'Zugkraft';
case 'G': return 'Gewicht';
case 'Ik_cond': return 'Kurzschlussstrom Leiter';
case 'Ik_screen': return 'Kurzschlussstrom Schirm';
case 'Ø': return 'Außen-Ø';
case 'cap': return 'Kapazität';
case 'X': return 'Reaktanz';
case 'rated_volt': return 'Nennspannung';
case 'D_screen': return 'Durchmesser über Schirm';
case 'S_screen': return 'Metallischer Schirm';
case 'cross_section': return 'Querschnitt';
case 'shape': return 'Leiterform';
case 'Ibl': return 'Strombelastbarkeit (Luft)';
case 'Ibe': return 'Strombelastbarkeit (Erde)';
case 'Cond': return 'Leitermaterial';
default:
return formatExcelHeaderLabel(args.excelKey);
}
@@ -356,6 +408,26 @@ function metaFullLabel(args: { key: string; excelKey: string; locale: 'en' | 'de
return 'CPR class';
case 'flame':
return 'Flame retardant';
case 'DI': return 'Diameter over insulation';
case 'RI': return 'DC resistance (20 °C)';
case 'Wi': return 'Insulation thickness';
case 'Wm': return 'Sheath thickness';
case 'Rbv': return 'Bending radius';
case 'Fzv': return 'Pulling force';
case 'G': return 'Weight';
case 'Ik_cond': return 'Short-circuit current conductor';
case 'Ik_screen': return 'Short-circuit current screen';
case 'Ø': return 'Outer diameter';
case 'cap': return 'Capacitance';
case 'X': return 'Reactance';
case 'rated_volt': return 'Rated voltage';
case 'D_screen': return 'Diameter over screen';
case 'S_screen': return 'Metallic screen';
case 'cross_section': return 'Cross-section';
case 'shape': return 'Conductor shape';
case 'Ibl': return 'Current rating (air)';
case 'Ibe': return 'Current rating (ground)';
case 'Cond': return 'Conductor material';
default:
return formatExcelHeaderLabel(args.excelKey);
}
@@ -450,7 +522,7 @@ function translateAbbreviation(abbrev: string, description: string, locale: 'en'
case 'Cond':
return 'Leiter';
case 'shape':
return 'Form';
return 'Leiterform';
case 'cap':
return 'Kapazität';
case 'X':
@@ -918,6 +990,7 @@ function buildExcelModel(args: { product: ProductData; locale: 'en' | 'de' }): B
}
function isMediumVoltageProduct(product: ProductData): boolean {
if (product.voltageType === 'medium-voltage') return true;
const hay = [product.slug, product.path, product.translationKey, ...(product.categories || []).map(c => c.name)]
.filter(Boolean)
.join(' ');
@@ -1038,7 +1111,7 @@ function buildMediumVoltageCrossSectionTableFromNewExcel(args: {
return {
key: col.colKey,
// Use the abbreviated title from the first row as the table header.
label: normalizeValue(col.colKey),
label: denseAbbrevLabel({ key: col.colKey, locale: args.locale, unit: col.unit }) || normalizeValue(col.colKey),
get: (rowIndex: number) => {
const srcRowIndex = indices[rowIndex];
const raw = normalizeValue(String((mv.rows[srcRowIndex] as Record<string, unknown>)?.[col.colKey] ?? ''));

View File

@@ -54,7 +54,7 @@ export function getLabels(locale: 'en' | 'de') {
return {
en: {
datasheet: 'Technical Datasheet',
description: 'DESCRIPTION',
description: 'APPLICATION',
technicalData: 'TECHNICAL DATA',
crossSection: 'Cross-sections/Voltage',
sku: 'SKU',
@@ -62,7 +62,7 @@ export function getLabels(locale: 'en' | 'de') {
},
de: {
datasheet: 'Technisches Datenblatt',
description: 'BESCHREIBUNG',
description: 'ANWENDUNG',
technicalData: 'TECHNISCHE DATEN',
crossSection: 'Querschnitte/Spannung',
sku: 'ARTIKELNUMMER',

View File

@@ -21,7 +21,7 @@ export function DatasheetDocument(props: { model: DatasheetModel; assets: Assets
const headerTitle = model.labels.datasheet;
// Dense tables require compact headers (no wrapping). Use standard abbreviations.
const firstColLabel = model.locale === 'de' ? 'Adern & QS' : 'Cores & CS';
const firstColLabel = model.locale === 'de' ? 'Adern & Querschnitt' : 'Cores & Cross-section';
return (
<Document>