/* global React, Card, Button, Input, Ic, Breadcrumb, VS, LoadingState, ErrorState, SchemaPicker, NormPicker */ // ============================================================ // LIST SCREEN // ============================================================ function OneTimeProtocolsScreen() { const [activeId, setActiveId] = React.useState(null); const [list, setList] = React.useState(null); const [err, setErr] = React.useState(''); const [busy, setBusy] = React.useState(false); const load = React.useCallback(() => { setList(null); setErr(''); VS.oneTimeProtocols() .then((r) => setList(r)) .catch((e) => setErr(e.message)); }, []); React.useEffect(() => { load(); }, [load]); async function createNew() { setBusy(true); try { const r = await VS.createOneTimeProtocol(); setActiveId(r.id); } catch (e) { setErr(e.message); } finally { setBusy(false); } } async function removeRow(id) { if (!confirm('Usunąć ten protokół?')) return; try { await VS.deleteOneTimeProtocol(id); load(); } catch (e) { alert('Błąd: ' + e.message); } } if (activeId) { return ( { setActiveId(null); load(); }} /> ); } return (
Raporty

Protokoły jednorazowe

Pomiary wibracji realizowane poza cyklem harmonogramowym.
{err && } {!err && !list && } {!err && list && list.length === 0 && (
Brak protokołów
Utwórz nowy protokół aby zacząć.
)} {!err && list && list.length > 0 && (
Zakład
Maszyna
Data
Ost. edycja
Autor
Akcje
{list.map((p, i) => (
setActiveId(p.id)} onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-sunken)'} onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'} >
{p.site_name || '—'}
{p.machine_name || '—'}
{p.data || '—'}
{p.updated_at ? p.updated_at.slice(0, 16).replace('T', ' ') : '—'}
{p.created_by || '—'}
e.stopPropagation()}>
))}
)}
); } // ============================================================ // EDITOR // ============================================================ const CEL_POMIARU_OPTS = [ 'Kontrolny', 'Odbiorczy', 'Powykonawczy', 'Diagnostyczny', 'Po remoncie', 'Po wyosiowaniu', ]; const SPRZET_OPTS = [ 'SKF Microlog Analyzer CMXA80', 'Prüftechnik Optalign smart RS', 'SKF QuickCollect', ]; const STAN_DYN_OPTS = [ 'Stan dynamiczny zgodnie z normą (ISO 10816-3) dopuszczalny.', 'Stan dynamiczny dopuszczalny — praca bez ograniczeń czasowych.', 'Stan dynamiczny wymaga obserwacji.', 'Stan dynamiczny niedopuszczalny — konieczna interwencja.', ]; const ZALECENIA_OPTS = [ 'Brak zaleceń.', 'Zalecany kontrolny pomiar drgań za 3 miesiące.', 'Zalecana wymiana łożysk.', 'Zalecane osiowanie zespołu.', 'Zalecane wyważenie dynamiczne.', ]; const UWAGI_OPTS = [ 'Bez uwag.', 'Wartości pozostawione po wyosiowaniu zespołu.', 'Pomiar po remoncie.', 'Maszyna pracowała w warunkach nominalnych.', ]; function emptyBearings() { return [1, 2, 3, 4].map((nr) => ({ nr, v_pion: null, env: null, acc: null, hfd: null, v_poz: null, v_osiowy: null, })); } function OneTimeProtocolEditor({ protocolId, onBack }) { const [protocol, setProtocol] = React.useState(null); const [err, setErr] = React.useState(''); const [sites, setSites] = React.useState([]); const [machines, setMachines] = React.useState([]); const [users, setUsers] = React.useState(null); // null = nieznane, [] = brak const [dirty, setDirty] = React.useState(false); const [busy, setBusy] = React.useState(false); const [msg, setMsg] = React.useState(''); const [schemaBust, setSchemaBust] = React.useState(0); const [showPicker, setShowPicker] = React.useState(false); const [showNormPicker, setShowNormPicker] = React.useState(false); const [normsList, setNormsList] = React.useState(null); const schemaFileRef = React.useRef(null); React.useEffect(() => { VS.oneTimeProtocol(protocolId) .then((p) => { // Ensure bearings array exists const bearings = Array.isArray(p.bearings) && p.bearings.length > 0 ? p.bearings : emptyBearings(); const osiowanie = p.osiowanie || { rozw_poz: null, prz_poz: null, rozw_pion: null, prz_pion: null }; setProtocol({ ...p, bearings, osiowanie }); }) .catch((e) => setErr(e.message)); VS.sites().then((s) => setSites(s || [])).catch(() => {}); // Try user-stamps (admin). Fallback: current user only. VS.userStamps() .then((list) => setUsers(list || [])) .catch(() => { // fallback — current user only VS.myStamp() .then((me) => { setUsers([{ user_id: me.user_id, username: me.username, role: 'user', name: me.name, cert_number: me.cert_number, has_image: me.has_image, }]); }) .catch(() => setUsers([])); }); }, [protocolId]); React.useEffect(() => { VS.norms().then((r) => setNormsList(r || [])).catch(() => setNormsList([])); }, []); // Load machines when site_id changes React.useEffect(() => { if (!protocol) return; if (protocol.site_id) { VS.siteMachines(protocol.site_id) .then((m) => setMachines(m || [])) .catch(() => setMachines([])); } else { setMachines([]); } }, [protocol && protocol.site_id]); function patch(p) { setProtocol((prev) => ({ ...prev, ...p })); setDirty(true); } function patchOsiowanie(p) { setProtocol((prev) => ({ ...prev, osiowanie: { ...prev.osiowanie, ...p } })); setDirty(true); } function updateBearing(idx, field, value) { setProtocol((prev) => { const bearings = prev.bearings.map((b, i) => (i === idx ? { ...b, [field]: value } : b)); return { ...prev, bearings }; }); setDirty(true); } function addBearing() { setProtocol((prev) => { const maxNr = prev.bearings.reduce((a, b) => Math.max(a, b.nr || 0), 0); const bearings = [...prev.bearings, { nr: maxNr + 1 || 1, v_pion: null, env: null, acc: null, hfd: null, v_poz: null, v_osiowy: null, }]; return { ...prev, bearings }; }); setDirty(true); } function removeBearing(idx) { setProtocol((prev) => ({ ...prev, bearings: prev.bearings.filter((_, i) => i !== idx) })); setDirty(true); } async function save() { if (!protocol) return; setBusy(true); setMsg(''); try { const payload = { site_id: protocol.site_id, site_name: protocol.site_name || '', machine_id: protocol.machine_id, machine_name: protocol.machine_name || '', data: protocol.data || null, cel_pomiaru: protocol.cel_pomiaru || '', sprzet: protocol.sprzet || '', opis: protocol.opis || '', stan_dynamiczny: protocol.stan_dynamiczny || '', zalecenia: protocol.zalecenia || '', uwagi: protocol.uwagi || '', osiowanie: protocol.osiowanie || {}, bearings: protocol.bearings || [], opracowal_user_id: protocol.opracowal_user_id, zatwierdzil_user_id: protocol.zatwierdzil_user_id, schema_library_id: protocol.schema_library_id ?? null, norm_id: protocol.norm_id ?? null, }; await VS.saveOneTimeProtocol(protocolId, payload); setDirty(false); setMsg('Zapisano.'); setTimeout(() => setMsg(''), 2500); } catch (e) { setMsg('Błąd: ' + e.message); } finally { setBusy(false); } } async function uploadSchema(e) { const file = e.target.files && e.target.files[0]; if (!file) return; setBusy(true); setMsg(''); try { await VS.uploadOneTimeSchemaImage(protocolId, file); // Wgrany custom wyłącza wybór z biblioteki — backend woli custom, ale // dla spójności zerujemy też schema_library_id i zapisujemy. setProtocol((prev) => ({ ...prev, has_schema_image: true, schema_library_id: null })); if (protocol && protocol.schema_library_id) { try { await VS.saveOneTimeProtocol(protocolId, { schema_library_id: null }); } catch (_) { /* best-effort */ } } setDirty(false); setSchemaBust((x) => x + 1); setMsg('Schemat wgrany.'); setTimeout(() => setMsg(''), 2500); } catch (err) { setMsg('Błąd: ' + err.message); } finally { setBusy(false); e.target.value = ''; } } async function pickFromLibrary(id, name) { setProtocol((prev) => ({ ...prev, schema_library_id: id, schema_library_name: name })); setDirty(true); } async function clearSchema() { setProtocol((prev) => ({ ...prev, schema_library_id: null })); setDirty(true); } async function removeProtocol() { if (!confirm('Usunąć ten protokół? Operacja nieodwracalna.')) return; try { await VS.deleteOneTimeProtocol(protocolId); onBack(); } catch (e) { alert('Błąd: ' + e.message); } } async function downloadPdf() { // zapisz najpierw żeby PDF był aktualny if (dirty) { await save(); } try { await VS.openOneTimePdf(protocolId); } catch (e) { alert('Błąd pobierania PDF: ' + e.message); } } if (err) return ; if (!protocol) return ; const siteOptions = (sites || []).map((s) => ({ id: s.id, label: s.name })); const machineOptions = (machines || []).map((m) => ({ id: m.id, label: m.name })); return (

Protokół jednorazowy #{protocolId}

{dirty ? ( ● Niezapisane zmiany ) : ( Wszystkie zmiany zapisane )} {msg && ( {msg} )}
{/* 1. Metadane */}
Metadane
patch({ site_name: val, site_id: id, machine_id: null, machine_name: protocol.machine_name })} /> patch({ machine_name: val, machine_id: id })} /> patch({ data: e.target.value })} style={inputStyle} /> patch({ cel_pomiaru: v })} placeholder="np. Kontrolny" /> patch({ sprzet: v })} placeholder="np. SKF Microlog Analyzer CMXA80" rows={2} />
{/* 2. Opis urządzenia */}
Opis urządzenia