52b7c20c2a
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m30s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m28s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 15s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 10s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m5s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m31s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 15s
Testy / Kontrola składni wszystkich warstw (push) Successful in 10s
build / build (push) Successful in 2m49s
Regresja: „Skompiluj" przeliczało horoskop od nowa z OKROJONYM zestawem opcji (tylko system domów + zodiak), więc jeśli przy horoskopie policzyłeś stacje, tabele (żywioły, faza Księżyca…) albo porównanie domów — w podsumowaniu ich NIE było. Zamiast pokazać to, co policzono, liczyło uboższą wersję. Zostaje czysty przelicz (bez trzymania dużego wyniku w przeglądarce), ale z TYMI SAMYMI opcjami co przy horoskopie: - `formsync`: synchronizuje między zakładkami też opcje — checkboxy (stacje, tabele) i wielo-checkbox (porównanie domów). Wcześniej umiał tylko `.value`. - „Skompiluj" (formularz): dostaje te same opcje; `compile_build` i `compile_pdf` przekazują je do logiki (stations/tables/house_systems). `compile.js` wysyła je w payloadzie PDF-a. - Wspólny plik `_result_tables.html`: podsumowanie renderuje DOKŁADNIE te same tabele co „Horoskop" (porównanie domów, stacje, aspekty, paralele, antyscja, żywioły/faza/godziny, Lots…). Każda sekcja pokazuje się tylko, gdy jej dane są w wyniku — opcja niepoliczona → sekcji nie ma (zgodnie z prośbą). (TODO: przełączyć też chart.html na ten include, by widoki nie mogły się rozjechać — na razie zgodność pilnowana ręcznie, jest komentarz w pliku.) Weryfikacja: render wspólnego pliku na bogatym wyniku pokazuje wszystkie sekcje. Testy: +8 (opcje niesione w /compile i /compile/pdf, sync checkboxów/multi, wspólny include). Prezentacja 202. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
173 lines
6.6 KiB
JavaScript
173 lines
6.6 KiB
JavaScript
// Zakładka „Skompiluj" — składanie raportu (PRE-23).
|
||
//
|
||
// Raport ma trzy kawałki liczone w różnych miejscach:
|
||
// 1. horoskop — liczy serwer przy wysłaniu tego formularza,
|
||
// 2. interpretacja natalna — z zakładki Interpretacje (natal.js),
|
||
// 3. predykcje okresowe — z zakładki Kalendarz (predictions.js).
|
||
//
|
||
// Punkty 2 i 3 mieszkają w magazynie przeglądarki, więc to tutaj je dokładamy.
|
||
// Odczytujemy je przez API tamtych modułów, a nie sięgając wprost do
|
||
// localStorage — dzięki temu format danych ma JEDNEGO właściciela.
|
||
//
|
||
// Pokazujemy też, CZEGO BRAKUJE. Bez tego użytkownik złożyłby niekompletny raport
|
||
// i dowiedział się o tym dopiero po otwarciu PDF-a.
|
||
(function () {
|
||
'use strict';
|
||
|
||
function esc(s) {
|
||
return String(s == null ? '' : s)
|
||
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||
}
|
||
|
||
function readNatal() {
|
||
return (window.astrololoNatal && window.astrololoNatal.read()) || null;
|
||
}
|
||
|
||
function readPredictions() {
|
||
return (window.astrololoPredictions && window.astrololoPredictions.read()) || [];
|
||
}
|
||
|
||
function item(ok, label, hint) {
|
||
return '<li class="' + (ok ? 'rdy-ok' : 'rdy-missing') + '">' +
|
||
(ok ? '✓ ' : '✗ ') + esc(label) +
|
||
(ok ? '' : ' <span class="muted small">— ' + esc(hint) + '</span>') + '</li>';
|
||
}
|
||
|
||
function renderReadiness(hasChart) {
|
||
var host = document.getElementById('readiness');
|
||
if (!host) return;
|
||
var natal = readNatal();
|
||
var preds = readPredictions();
|
||
var parts = [
|
||
item(hasChart, 'Policzony horoskop', 'wypełnij dane i kliknij „Złóż podsumowanie"'),
|
||
item(!!natal, 'Interpretacja natalna',
|
||
'wygeneruj ją na zakładce Interpretacje — zapamięta się sama'),
|
||
item(preds.length > 0,
|
||
'Predykcje okresowe' + (preds.length ? ' (' + preds.length + ')' : ''),
|
||
'policz horoskop na wybrany okres w Kalendarzu')
|
||
];
|
||
host.innerHTML = '<div class="meta">Materiał do raportu</div><ul class="readiness">' +
|
||
parts.join('') + '</ul>';
|
||
}
|
||
|
||
function renderNatal() {
|
||
var host = document.getElementById('reportNatal');
|
||
if (!host) return;
|
||
var natal = readNatal();
|
||
if (!natal) {
|
||
host.innerHTML = '<div class="meta">Interpretacja natalna</div>' +
|
||
'<p class="muted small">Brak — wygeneruj ją na zakładce Interpretacje.</p>';
|
||
return;
|
||
}
|
||
host.innerHTML = '<div class="meta">Interpretacja natalna ' +
|
||
'<span class="muted small">· zapamiętana ' + esc(String(natal.saved_at).slice(0, 10)) +
|
||
'</span></div><div class="report-text">' + esc(natal.text) + '</div>';
|
||
}
|
||
|
||
function renderPredictions() {
|
||
var host = document.getElementById('reportPredictions');
|
||
if (!host) return;
|
||
var preds = readPredictions();
|
||
if (!preds.length) {
|
||
host.innerHTML = '<div class="meta">Predykcje okresowe</div>' +
|
||
'<p class="muted small">Brak — policz horoskop na wybrany okres w Kalendarzu.</p>';
|
||
return;
|
||
}
|
||
var blocks = preds.map(function (p) {
|
||
return '<div class="meta">' + esc(p.from_date) + ' – ' + esc(p.to_date) + '</div>' +
|
||
'<div class="report-text">' + esc(p.text) + '</div>';
|
||
}).join('');
|
||
host.innerHTML = '<div class="meta">Predykcje okresowe (' + preds.length + ')</div>' + blocks;
|
||
}
|
||
|
||
function ready(fn) {
|
||
if (document.readyState !== 'loading') fn();
|
||
else document.addEventListener('DOMContentLoaded', fn);
|
||
}
|
||
|
||
// ── PDF (PRE-24) ────────────────────────────────────────────────────
|
||
// Części od AI mieszkają w przeglądarce, więc raport składamy TU i wysyłamy
|
||
// do serwera, który dokłada kosmogram i woła usługę render.
|
||
function formData() {
|
||
function v(name) {
|
||
var el = document.querySelector('[name=' + name + ']');
|
||
return el ? el.value : '';
|
||
}
|
||
function checked(name) {
|
||
var el = document.querySelector('[name=' + name + ']');
|
||
return !!(el && el.checked);
|
||
}
|
||
function multi(name) {
|
||
var out = [];
|
||
document.querySelectorAll('[name=' + name + ']:checked').forEach(function (el) { out.push(el.value); });
|
||
return out;
|
||
}
|
||
// Opcje (stacje, tabele, porównanie domów) MUSZĄ jechać do PDF-a — inaczej
|
||
// PDF liczyłby okrojony horoskop i miałby braki względem podsumowania.
|
||
return {
|
||
date: v('date'), time: v('time'), tz_offset: v('tz_offset'),
|
||
lat: v('lat'), lon: v('lon'),
|
||
house_system: v('house_system'), zodiac: v('zodiac'),
|
||
house_systems: multi('house_systems'),
|
||
stations: checked('stations'), tables: checked('tables'),
|
||
place: (document.querySelector('#geoSearch') || {}).value || ''
|
||
};
|
||
}
|
||
|
||
function download(blob) {
|
||
var url = URL.createObjectURL(blob);
|
||
var a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = 'raport.pdf';
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
a.remove();
|
||
// Zwalniamy obiekt dopiero po kliknięciu — wcześniej przeglądarka nie zdąży
|
||
// rozpocząć pobierania.
|
||
setTimeout(function () { URL.revokeObjectURL(url); }, 4000);
|
||
}
|
||
|
||
function buildPdf(btn, note) {
|
||
var person = (document.querySelector('[name=person]') || {}).value || '';
|
||
var payload = {
|
||
person: person,
|
||
data: formData(),
|
||
natal: readNatal() || {},
|
||
predictions: readPredictions()
|
||
};
|
||
btn.disabled = true;
|
||
note.textContent = 'Składam PDF — LaTeX potrzebuje chwili przy obszernym tekście…';
|
||
fetch('/compile/pdf', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(payload)
|
||
}).then(function (r) {
|
||
if (!r.ok) {
|
||
return r.json().catch(function () { return {}; }).then(function (d) {
|
||
throw new Error(d.detail || ('HTTP ' + r.status));
|
||
});
|
||
}
|
||
return r.blob();
|
||
}).then(function (blob) {
|
||
download(blob);
|
||
note.textContent = 'Gotowe — PDF pobrany.';
|
||
}).catch(function (e) {
|
||
note.textContent = 'Nie udało się złożyć PDF-a: ' + e.message;
|
||
}).finally(function () {
|
||
btn.disabled = false;
|
||
});
|
||
}
|
||
|
||
ready(function () {
|
||
if (!document.getElementById('readiness')) return; // nie ta zakładka
|
||
// Horoskop jest w dokumencie tylko po wysłaniu formularza.
|
||
renderReadiness(!!document.getElementById('reportPerson'));
|
||
renderNatal();
|
||
renderPredictions();
|
||
|
||
var btn = document.getElementById('pdfBtn');
|
||
var note = document.getElementById('pdfNote');
|
||
if (btn && note) btn.addEventListener('click', function () { buildPdf(btn, note); });
|
||
});
|
||
})();
|