248 lines
7.8 KiB
JavaScript
248 lines
7.8 KiB
JavaScript
import { esc } from './utils.js';
|
|
import { ANLAGEN_GRUPPE_PLACEHOLDER } from './constants.js';
|
|
|
|
/** Baut das extras-Objekt aus dem Maschinen-Bearbeitungsformular (Anlagenliste). */
|
|
export function collectExtrasFromMachineForm(form, machine) {
|
|
const prev =
|
|
machine.extras && typeof machine.extras === 'object'
|
|
? JSON.parse(JSON.stringify(machine.extras))
|
|
: {};
|
|
const beschr = prev._beschriftungZeile9;
|
|
const werte = prev._werteAlsListe;
|
|
const gruppe = prev._gruppeZeile7;
|
|
if (
|
|
Array.isArray(beschr) &&
|
|
Array.isArray(werte) &&
|
|
beschr.length === werte.length
|
|
) {
|
|
const n = beschr.length;
|
|
const newWerte = [];
|
|
for (let i = 0; i < n; i++) {
|
|
newWerte.push(String(form.elements[`extra_wert_${i}`]?.value ?? ''));
|
|
}
|
|
prev._werteAlsListe = newWerte;
|
|
return prev;
|
|
}
|
|
const out = {};
|
|
for (const k of Object.keys(prev)) {
|
|
if (k.startsWith('_')) out[k] = prev[k];
|
|
}
|
|
const kvKeys = Object.keys(prev).filter((k) => !k.startsWith('_'));
|
|
for (let i = 0; i < kvKeys.length; i++) {
|
|
const key = kvKeys[i];
|
|
out[key] = String(form.elements[`extras_kv_val_${i}`]?.value ?? '');
|
|
}
|
|
return out;
|
|
}
|
|
|
|
export function extrasTableHtml(extras, opts) {
|
|
const editable = opts && opts.editable === true;
|
|
if (!extras || typeof extras !== 'object') {
|
|
if (editable) {
|
|
return `
|
|
<div class="card">
|
|
<h3>Anlagenliste (ITT)</h3>
|
|
<p class="muted">Keine Anlagendaten gespeichert — nichts zu bearbeiten.</p>
|
|
</div>`;
|
|
}
|
|
return '';
|
|
}
|
|
|
|
const beschr = extras._beschriftungZeile9;
|
|
const gruppe = extras._gruppeZeile7;
|
|
const werte = extras._werteAlsListe;
|
|
|
|
if (
|
|
Array.isArray(beschr) &&
|
|
Array.isArray(werte) &&
|
|
beschr.length === werte.length
|
|
) {
|
|
const g =
|
|
Array.isArray(gruppe) && gruppe.length === beschr.length
|
|
? gruppe
|
|
: null;
|
|
|
|
if (editable) {
|
|
const body = beschr
|
|
.map((label, i) => {
|
|
const v = werte[i];
|
|
const grp = g ? String(g[i] ?? '') : '';
|
|
return `<tr>
|
|
<td class="muted">${esc(grp)}</td>
|
|
<th>${esc(String(label || `Spalte ${i + 1}`))}</th>
|
|
<td><input type="text" name="extra_wert_${i}" value="${esc(String(v ?? ''))}" class="extras-cell-input" autocomplete="off" /></td>
|
|
</tr>`;
|
|
})
|
|
.join('');
|
|
return `
|
|
<div class="card">
|
|
<h3>Anlagenliste (bearbeiten)</h3>
|
|
<p class="muted">Nur die Spalte „Wert“ ist bearbeitbar. Gruppe und Beschreibung bleiben wie importiert.</p>
|
|
<div class="table-wrap">
|
|
<table class="extras-table anlagen-voll">
|
|
<colgroup>
|
|
<col class="anlagen-col-gruppe" />
|
|
<col class="anlagen-col-beschr" />
|
|
<col class="anlagen-col-wert" />
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th>Gruppe (Z. 7)</th>
|
|
<th>Beschreibung (Z. 9)</th>
|
|
<th>Wert</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>${body}</tbody>
|
|
</table>
|
|
</div>
|
|
</div>`;
|
|
}
|
|
|
|
if (g) {
|
|
const n = beschr.length;
|
|
const groupForRow = [];
|
|
let cur = '';
|
|
for (let i = 0; i < n; i++) {
|
|
const raw = g[i] != null ? String(g[i]).trim() : '';
|
|
if (raw) cur = raw;
|
|
groupForRow[i] = cur || ANLAGEN_GRUPPE_PLACEHOLDER;
|
|
}
|
|
const segments = [];
|
|
let segStart = 0;
|
|
for (let i = 1; i <= n; i++) {
|
|
if (i === n || groupForRow[i] !== groupForRow[i - 1]) {
|
|
segments.push({ from: segStart, to: i, key: groupForRow[segStart] });
|
|
segStart = i;
|
|
}
|
|
}
|
|
|
|
const gruppenTitel = (key) =>
|
|
key === ANLAGEN_GRUPPE_PLACEHOLDER ? 'Sonstiges' : key;
|
|
|
|
const tbodies = segments
|
|
.map((seg, idx) => {
|
|
const spacer =
|
|
idx > 0
|
|
? `<tbody class="anlagen-gruppe-spacer"><tr><td colspan="2"></td></tr></tbody>`
|
|
: '';
|
|
const titel = gruppenTitel(seg.key);
|
|
const kopf = `<tr class="anlagen-gruppe-kopf"><td colspan="2">${esc(titel)}</td></tr>`;
|
|
const zeilen = [];
|
|
for (let i = seg.from; i < seg.to; i++) {
|
|
const v = werte[i];
|
|
const show = v !== '' && v != null;
|
|
const label = String(beschr[i] || `Spalte ${i + 1}`);
|
|
zeilen.push(
|
|
`<tr data-empty="${show ? '0' : '1'}"><th>${esc(label)}</th><td>${esc(String(v ?? ''))}</td></tr>`,
|
|
);
|
|
}
|
|
return `${spacer}<tbody class="anlagen-gruppe">${kopf}${zeilen.join('')}</tbody>`;
|
|
})
|
|
.join('');
|
|
|
|
return `
|
|
<div class="card">
|
|
<h3>Anlagenliste</h3>
|
|
<div class="table-wrap">
|
|
<table class="extras-table anlagen-voll gruppiert">
|
|
<colgroup>
|
|
<col class="anlagen-col-beschr" />
|
|
<col class="anlagen-col-wert" />
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th>Beschreibung (Z. 9)</th>
|
|
<th>Wert</th>
|
|
</tr>
|
|
</thead>
|
|
${tbodies}
|
|
</table>
|
|
</div>
|
|
</div>`;
|
|
}
|
|
|
|
const body = beschr
|
|
.map((label, i) => {
|
|
const v = werte[i];
|
|
const show = v !== '' && v != null;
|
|
const grp = '';
|
|
return `<tr data-empty="${show ? '0' : '1'}">
|
|
<td class="muted">${esc(grp)}</td>
|
|
<th>${esc(String(label || `Spalte ${i + 1}`))}</th>
|
|
<td>${esc(String(v ?? ''))}</td>
|
|
</tr>`;
|
|
})
|
|
.join('');
|
|
return `
|
|
<div class="card">
|
|
<h3>Anlagenliste (alle Spalten · Zeile 9 = Beschreibung)</h3>
|
|
<p class="muted">Gruppe = Zeile 7 im Blatt „Anlagen“, Beschreibung = Zeile 9.</p>
|
|
<div class="table-wrap">
|
|
<table class="extras-table anlagen-voll">
|
|
<colgroup>
|
|
<col class="anlagen-col-gruppe" />
|
|
<col class="anlagen-col-beschr" />
|
|
<col class="anlagen-col-wert" />
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th>Gruppe (Z. 7)</th>
|
|
<th>Beschreibung (Z. 9)</th>
|
|
<th>Wert</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>${body}</tbody>
|
|
</table>
|
|
</div>
|
|
</div>`;
|
|
}
|
|
|
|
const kvEntries = Object.entries(extras).filter(([k]) => !k.startsWith('_'));
|
|
if (editable) {
|
|
if (kvEntries.length === 0) {
|
|
return `
|
|
<div class="card">
|
|
<h3>Daten aus Anlagenliste (ITT)</h3>
|
|
<p class="muted">Keine zusätzlichen Felder — nichts zu bearbeiten.</p>
|
|
</div>`;
|
|
}
|
|
const rows = kvEntries
|
|
.map(
|
|
([k, v], i) =>
|
|
`<tr>
|
|
<th>${esc(k)}</th>
|
|
<td><input type="text" name="extras_kv_val_${i}" value="${esc(String(v))}" class="extras-cell-input" autocomplete="off" /></td>
|
|
</tr>`,
|
|
)
|
|
.join('');
|
|
return `
|
|
<div class="card">
|
|
<h3>Daten aus Anlagenliste (ITT)</h3>
|
|
<p class="muted">Nur die Werte sind bearbeitbar; Feldnamen sind fest.</p>
|
|
<div class="table-wrap">
|
|
<table class="extras-table">
|
|
<tbody>${rows}</tbody>
|
|
</table>
|
|
</div>
|
|
</div>`;
|
|
}
|
|
|
|
const rows = kvEntries
|
|
.filter(([, v]) => v !== '' && v != null)
|
|
.map(
|
|
([k, v]) =>
|
|
`<tr><th>${esc(k)}</th><td>${esc(String(v))}</td></tr>`,
|
|
)
|
|
.join('');
|
|
if (!rows) return '';
|
|
return `
|
|
<div class="card">
|
|
<h3>Daten aus Anlagenliste (ITT)</h3>
|
|
<div class="table-wrap">
|
|
<table class="extras-table">
|
|
<tbody>${rows}</tbody>
|
|
</table>
|
|
</div>
|
|
</div>`;
|
|
}
|