feat: v3.0 - canvas editor, JSON-only, no Excel, new UI
Some checks failed
Build & Push Docker / build (push) Has been cancelled

- Remove all Excel code (import, export, template, pandas, openpyxl)
- New canvas-based schedule editor with drag & drop (interact.js)
- Modern 3-panel UI: sidebar, canvas, documentation tab
- New data model: Block with id/date/start/end, ProgramType with id/name/color
- Clean API: GET /api/health, POST /api/validate, GET /api/sample, POST /api/generate-pdf
- Rewritten PDF generator using ScenarioDocument directly (no DataFrame)
- Professional PDF output: dark header, colored blocks, merged cells, legend, footer
- Sample JSON: "Zimní výjezd oddílu" with 11 blocks, 3 program types
- 30 tests passing (API, core models, PDF generation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-20 17:02:51 +01:00
parent e2bdadd0ce
commit 25fd578543
27 changed files with 2004 additions and 3016 deletions

View File

@@ -1,5 +1,5 @@
/**
* API fetch wrapper for Scenar Creator.
* API fetch wrapper for Scenar Creator v3.
*/
const API = {
@@ -9,10 +9,9 @@ const API = {
opts.headers = { 'Content-Type': 'application/json' };
opts.body = JSON.stringify(body);
} else {
opts.body = body; // FormData
opts.body = body;
}
const res = await fetch(url, opts);
return res;
return fetch(url, opts);
},
async postJson(url, body) {
@@ -33,21 +32,18 @@ const API = {
return res.blob();
},
async postFormData(url, formData) {
const res = await this.post(url, formData, false);
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }));
throw new Error(err.detail || 'API error');
}
return res.json();
},
async get(url) {
const res = await fetch(url);
if (!res.ok) throw new Error(res.statusText);
return res.json();
},
async getBlob(url) {
const res = await fetch(url);
if (!res.ok) throw new Error(res.statusText);
return res.blob();
},
downloadBlob(blob, filename) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');