V0.1
This commit is contained in:
247
public/js/core/machine-extras.js
Normal file
247
public/js/core/machine-extras.js
Normal file
@@ -0,0 +1,247 @@
|
||||
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>`;
|
||||
}
|
||||
Reference in New Issue
Block a user