This commit is contained in:
2026-01-24 21:44:14 +01:00
parent d90d7502c3
commit 7e94feaf19
100 changed files with 411 additions and 24 deletions

View File

@@ -283,6 +283,125 @@ function denseAbbrevLabel(args: { key: string; locale: 'en' | 'de'; unit?: strin
}
}
function translateAbbreviation(abbrev: string, description: string, locale: 'en' | 'de'): string {
const normalizedDesc = normalizeValue(description);
if (!normalizedDesc) return description;
// German translations for common abbreviations
if (locale === 'de') {
switch (abbrev) {
case 'DI':
return 'Durchmesser über Isolation';
case 'RI':
return 'Widerstand Leiter';
case 'Wi':
return 'Isolationsdicke';
case 'Ibl':
return 'Strombelastbarkeit Luft';
case 'Ibe':
return 'Strombelastbarkeit Erde';
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 'Cond':
return 'Leiter';
case 'shape':
return 'Form';
case 'cap':
return 'Kapazität';
case 'X':
return 'Reaktanz';
case 'test_volt':
return 'Prüfspannung';
case 'rated_volt':
return 'Nennspannung';
case 'temp_range':
return 'Temperaturbereich';
case 'max_op_temp':
return 'Leitertemperatur (max.)';
case 'max_sc_temp':
return 'Kurzschlusstemperatur (max.)';
case 'min_store_temp':
return 'Minimale Lagertemperatur';
case 'min_lay_temp':
return 'Minimale Verlegetemperatur';
case 'cpr':
return 'CPR-Klasse';
case 'flame':
return 'Flammhemmend';
default:
return normalizedDesc;
}
}
// English translations for common abbreviations
switch (abbrev) {
case 'DI':
return 'Diameter over insulation';
case 'RI':
return 'DC resistance';
case 'Wi':
return 'Insulation thickness';
case 'Ibl':
return 'Current rating in air';
case 'Ibe':
return 'Current rating in ground';
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 'Cond':
return 'Conductor';
case 'shape':
return 'Shape';
case 'cap':
return 'Capacitance';
case 'X':
return 'Reactance';
case 'test_volt':
return 'Test voltage';
case 'rated_volt':
return 'Rated voltage';
case 'temp_range':
return 'Operating temperature range';
case 'max_op_temp':
return 'Max operating temperature';
case 'max_sc_temp':
return 'Max short-circuit temperature';
case 'min_store_temp':
return 'Min storage temperature';
case 'min_lay_temp':
return 'Min laying temperature';
case 'cpr':
return 'CPR class';
case 'flame':
return 'Flame retardant';
default:
return normalizedDesc;
}
}
function summarizeOptions(options: string[] | undefined): string {
const vals = (options || []).map(normalizeValue).filter(Boolean);
if (vals.length === 0) return '';
@@ -658,9 +777,10 @@ function buildMediumVoltageCrossSectionTableFromNewExcel(args: {
for (const col of abbrevCols) {
const description = normalizeValue(String(mv.headerRow[col.colKey] || ''));
if (description && description !== col.colKey) {
const translatedDescription = translateAbbreviation(col.colKey, description, args.locale);
legendItems.push({
label: col.colKey,
value: description,
value: translatedDescription,
});
}
}

View File

@@ -15,6 +15,7 @@ export interface ProductData {
name: string;
options: string[];
}>;
voltageType?: string;
}
export type KeyValueItem = { label: string; value: string; unit?: string };

View File

@@ -41,13 +41,13 @@ export function DatasheetDocument(props: { model: DatasheetModel; assets: Assets
</View>
{model.product.descriptionText ? (
<Section title={model.labels.description}>
<Section title={model.labels.description} minPresenceAhead={24}>
<Text style={styles.body}>{model.product.descriptionText}</Text>
</Section>
) : null}
{model.technicalItems.length ? (
<Section title={model.labels.technicalData}>
<Section title={model.labels.technicalData} minPresenceAhead={24}>
<KeyValueGrid items={model.technicalItems} />
</Section>
) : null}
@@ -56,13 +56,15 @@ export function DatasheetDocument(props: { model: DatasheetModel; assets: Assets
{/*
Render all voltage sections in a single flow so React-PDF can paginate naturally.
This avoids hard page breaks that waste remaining whitespace at the bottom of a page.
Each table section has break={false} to prevent breaking within individual tables,
but the overall flow allows tables to move to the next page if needed.
*/}
<Page size="A4" style={styles.page}>
<Header title={headerTitle} logoDataUrl={assets.logoDataUrl} qrDataUrl={assets.qrDataUrl} />
<Footer locale={model.locale} siteUrl={CONFIG.siteUrl} />
{model.voltageTables.map((t: DatasheetVoltageTable) => (
<View key={t.voltageLabel} style={{ marginBottom: 14 }} break={false}>
<View key={t.voltageLabel} style={{ marginBottom: 14 }} break={false} minPresenceAhead={24}>
<Text style={styles.sectionTitle}>{`${model.labels.crossSection}${t.voltageLabel}`}</Text>
<DenseTable table={{ columns: t.columns, rows: t.rows }} firstColLabel={firstColLabel} />
@@ -70,7 +72,7 @@ export function DatasheetDocument(props: { model: DatasheetModel; assets: Assets
))}
{model.legendItems.length ? (
<Section title={model.locale === 'de' ? 'ABKÜRZUNGEN' : 'ABBREVIATIONS'}>
<Section title={model.locale === 'de' ? 'ABKÜRZUNGEN' : 'ABBREVIATIONS'} minPresenceAhead={24}>
<KeyValueGrid items={model.legendItems} />
</Section>
) : null}

View File

@@ -141,7 +141,7 @@ export function DenseTable(props: {
const headerFontSize = cols.length >= 14 ? 5.7 : cols.length >= 12 ? 5.9 : cols.length >= 10 ? 6.2 : 6.6;
return (
<View style={styles.tableWrap} break={false}>
<View style={styles.tableWrap} break={false} minPresenceAhead={24}>
<View style={styles.tableHeader} wrap={false}>
<View style={{ width: cfgW }}>
<Text

View File

@@ -26,17 +26,18 @@ export function KeyValueGrid(props: { items: KeyValueItem[] }): React.ReactEleme
key={`${left.label}-${rowIndex}`}
style={[styles.kvRow, rowIndex % 2 === 0 ? styles.kvRowAlt : null, isLast ? styles.kvRowLast : null]}
wrap={false}
minPresenceAhead={12}
>
<View style={[styles.kvCell, { width: '23%' }]}>
<View style={[styles.kvCell, { width: '18%' }]}>
<Text style={styles.kvLabelText}>{left.label}</Text>
</View>
<View style={[styles.kvCell, styles.kvMidDivider, { width: '27%' }]}>
<View style={[styles.kvCell, styles.kvMidDivider, { width: '32%' }]}>
<Text style={styles.kvValueText}>{leftValue}</Text>
</View>
<View style={[styles.kvCell, { width: '23%' }]}>
<View style={[styles.kvCell, { width: '18%' }]}>
<Text style={styles.kvLabelText}>{right?.label || ''}</Text>
</View>
<View style={[styles.kvCell, { width: '27%' }]}>
<View style={[styles.kvCell, { width: '32%' }]}>
<Text style={styles.kvValueText}>{rightValue}</Text>
</View>
</View>