1
0
Files

163 lines
11 KiB
HTML

<!doctype html>
<html lang="lv">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MK sēde</title>
<style>
:root { --bg:#ffffff; --fg:#1d2329; --muted:#5f6b76; --line:#dde2e7; --soft:#f4f6f8; --accent:#0b5cad; --tag:#eef3f9; --warn:#8a5a00; --warnbg:#fff4dc; --ok:#1d6b3a; --okbg:#e5f4ea; }
@media (prefers-color-scheme: dark) { :root { --bg:#16191d; --fg:#e4e8ec; --muted:#9aa5b0; --line:#2c3238; --soft:#1e2328; --accent:#6aa7e8; --tag:#1f2a36; --warn:#e8c06a; --warnbg:#3a2f16; --ok:#7fd19b; --okbg:#173022; } }
* { box-sizing: border-box; }
body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
main { max-width: 1000px; margin: 0 auto; padding: 16px; }
h1 { font-size: 20px; margin: 0 0 4px; }
h2 { font-size: 15px; margin: 22px 0 8px; padding-bottom: 4px; border-bottom: 1px solid var(--line); }
.meta, .muted { color: var(--muted); font-size: 13px; }
.bar { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin: 12px 0; }
input[type=search], select { font: inherit; color: var(--fg); background: var(--bg); border:1px solid var(--line); border-radius:6px; padding:6px 8px; }
input[type=search] { flex: 1 1 240px; }
.item { border:1px solid var(--line); border-radius:8px; margin: 8px 0; }
.item > summary { list-style:none; cursor:pointer; padding: 8px 10px; display:grid; grid-template-columns: 44px 1fr auto; gap: 8px; align-items: baseline; }
.item > summary::-webkit-details-marker { display:none; }
.item[open] > summary { border-bottom:1px solid var(--line); background: var(--soft); border-radius: 8px 8px 0 0; }
.n { font-weight: 600; color: var(--muted); }
.tap { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 12px; }
.tap a { color: var(--accent); }
.tag { display:inline-block; padding: 0 7px; border-radius: 9px; background: var(--tag); font-size: 12px; margin-right: 4px; white-space: nowrap; }
.st-Pieņemts { background: var(--okbg); color: var(--ok); }
.st-Atlikts { background: var(--warnbg); color: var(--warn); }
.body { padding: 8px 12px 12px; }
.dec { margin-top: 10px; }
.dec h3 { font-size: 13px; margin: 0 0 6px; color: var(--muted); font-weight: 600; }
.pt { display:grid; grid-template-columns: 44px 1fr; gap: 6px; padding: 3px 0; }
.pt .pn { color: var(--muted); text-align: right; }
.sub { margin-left: 24px; }
.chips { margin-top: 2px; }
.chip-dl { background: var(--warnbg); color: var(--warn); }
.quote { margin: 4px 0 4px 0; padding-left: 10px; border-left: 3px solid var(--line); color: var(--muted); }
.note { color: var(--muted); font-size: 12px; margin-top: 16px; }
.err { color: #b3261e; }
.pgv { display:none; color: var(--muted); font-size: 12px; margin-bottom: 8px; }
</style>
</head>
<body>
<main>
<div class="pgv" id="pgv"></div>
<h1 id="title">MK sēde</h1>
<div class="meta" id="meta">Ielādē…</div>
<div class="bar">
<input type="search" id="q" placeholder="Meklēt jautājumos un lēmumu tekstā (piemēram, Telia, 26-TA-2145, ministrijai)" aria-label="Meklēt">
<select id="kind" aria-label="Punkta veids">
<option value="">Visi punkti</option>
<option value="deadline">Ar termiņu</option>
<option value="task">Uzdevumi institūcijām</option>
</select>
</div>
<div id="out"></div>
<p class="note">Punkta teksts — burtiski kā TAP portālā. Darbības veids, adresāti un termiņš ir izgūti no teksta ar noteikumiem; juridiski saistošs ir teksts.
Lēmumu teksts ar statusu „projekts” — kā pievienots darba kārtībai; sēdē to var grozīt. PPPA koncepcijas demonstrācija, nav oficiāls valsts dokuments.</p>
</main>
<script>
(function () {
"use strict";
var NS = "urn:pppa:vpk:mk-lemumi:0.1", DOC = null;
var KIND = { note:"zināšanai", adopt:"pieņemt", approve:"apstiprināt", support:"atbalstīt", reject:"neatbalstīt", invite:"aicināt",
task:"uzdevums", allocate:"piešķirt", permit:"atļaut", authorise:"pilnvarot", determine:"noteikt", amend:"grozījums",
repeal:"atcelt", transfer:"nodot", purchase:"pirkt", establish:"izveidot", appoint:"iecelt", dismiss:"atbrīvot", part:"", provision:"" };
function $(id) { return document.getElementById(id); }
function kids(el, name) { return el ? Array.prototype.filter.call(el.childNodes, function (n) { return n.nodeType === 1 && n.localName === name && n.namespaceURI === NS; }) : []; }
function kid(el, name) { return kids(el, name)[0]; }
function txt(el, name) { var k = kid(el, name); return k ? k.textContent.trim() : ""; }
function esc(s) { return String(s == null ? "" : s).replace(/[&<>"]/g, function (c) { return { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c]; }); }
function pointHtml(p, depth) {
var chips = "", k = p.getAttribute("kind");
if (KIND[k]) chips += '<span class="tag">' + esc(KIND[k]) + "</span>";
kids(p, "Deadline").forEach(function (d) { chips += '<span class="tag chip-dl">līdz ' + esc(d.getAttribute("date")) + "</span>"; });
kids(p, "Party").forEach(function (x) { chips += '<span class="tag" title="' + esc(x.getAttribute("org") || x.getAttribute("atvk") || "") + '">' + esc(x.textContent) + "</span>"; });
var quotes = kids(p, "Quote").map(function (q) { return '<div class="quote">' + esc(q.textContent) + "</div>"; }).join("");
return '<div class="pt' + (depth ? " sub" : "") + '"><div class="pn">' + esc(p.getAttribute("n")) + "</div><div>" + esc(txt(p, "Text")) + quotes +
(chips ? '<div class="chips">' + chips + "</div>" : "") + "</div></div>" + kids(p, "Point").map(function (c) { return pointHtml(c, depth + 1); }).join("");
}
function render() {
if (!DOC) return;
var q = $("q").value.trim().toLowerCase(), f = $("kind").value, root = DOC.documentElement, html = "", shown = 0, total = 0;
kids(root, "Section").forEach(function (s) {
var items = kids(s, "Item").filter(function (it) {
total++;
var all = it.textContent.toLowerCase() + " " + (it.getAttribute("tap") || "").toLowerCase();
if (q && all.indexOf(q) < 0) return false;
if (f === "deadline" && !it.getElementsByTagNameNS(NS, "Deadline").length) return false;
if (f === "task" && !Array.prototype.some.call(it.getElementsByTagNameNS(NS, "Point"), function (p) { return p.getAttribute("kind") === "task"; })) return false;
return true;
});
if (!items.length) return;
html += "<h2>" + esc(s.getAttribute("n")) + ". " + esc(txt(s, "Title")) + "</h2>";
items.forEach(function (it) {
shown++;
var la = kid(it, "LegalAct"), tap = it.getAttribute("tap") || "", st = it.getAttribute("status");
var flags = (it.getAttribute("restricted") === "true" ? '<span class="tag">IP</span>' : "") +
(it.getAttribute("addedLate") === "true" ? '<span class="tag">iekļauts papildus</span>' : "") +
(it.getAttribute("postponed") === "true" ? '<span class="tag">atlikts</span>' : "");
var resp = kid(it, "Responsible");
var decs = kids(it, "Decision").map(function (d) {
var head = kids(d, "Heading").map(function (h) { return h.textContent; }).join(" · ");
return '<div class="dec"><h3>' + esc(d.getAttribute("document")) + (d.getAttribute("textStatus") === "draft" ? " (projekts)" : "") +
(head ? ' — <span class="muted">' + esc(head) + "</span>" : "") + "</h3>" +
kids(d, "Point").map(function (p) { return pointHtml(p, 0); }).join("") + "</div>";
}).join("");
html += '<details class="item"' + (q || f ? " open" : "") + "><summary><span class=\"n\">" + esc(it.getAttribute("n")) + "</span><span>" +
esc(txt(it, "Title")) + '<br><span class="tap">' + (la ? '<a href="' + esc(txt(la, "Url")) + '" target="_blank" rel="noopener">' + esc(tap) + "</a>" : esc(tap)) +
"</span> " + flags + '<span class="muted">' + esc(txt(it, "Presenter")) + (resp ? " · " + esc(resp.textContent) : "") + "</span></span>" +
'<span class="tag st-' + esc(st) + '">' + esc(st) + "</span></summary><div class=\"body\">" +
(decs || '<span class="muted">Lēmuma teksts TAP darba kārtībā nav publicēts.</span>') + "</div></details>";
});
});
$("out").innerHTML = html || '<p class="muted">Nekas nav atrasts.</p>';
}
function show(xmlText) {
DOC = new DOMParser().parseFromString(xmlText, "application/xml");
var root = DOC.documentElement;
if (!root || root.localName !== "CabinetMeeting" || root.namespaceURI !== NS) throw new Error("datne nav MK sēde");
var md = kid(root, "Metadata"), src = kid(md, "Source"), dv = kids(md, "DataVersion")[0], pr = kid(md, "Protocol");
$("title").textContent = txt(md, "Title");
var items = root.getElementsByTagNameNS(NS, "Item").length, points = root.getElementsByTagNameNS(NS, "Point").length;
$("meta").innerHTML = esc(txt(md, "Start").replace("T", " ").slice(0, 16)) + " · valdība " + esc(root.getAttribute("government")) +
(pr ? " · protokols Nr. " + esc(pr.getAttribute("number")) : " · protokols vēl nav publicēts") +
" · " + items + " jautājumi, " + points + " lēmumu punkti · datu versija " + esc(dv.getAttribute("number")) +
' · <a href="' + esc(txt(src, "Url")) + '" target="_blank" rel="noopener">TAP</a>';
render();
}
function fail(e) { $("meta").innerHTML = '<span class="err">Neizdevās ielādēt datni: ' + esc(e.message || e) + "</span>"; }
$("q").addEventListener("input", render);
$("kind").addEventListener("change", render);
function pgvFetch(url) {
return new Promise(function (res, rej) {
var tm = setTimeout(function () { removeEventListener("message", hd); rej(new Error("PGV_FETCH timeout")); }, 15000);
function hd(ev) { var m = ev.data; if (!m || m.type !== "PGV_FETCH_RESULT" || m.url !== url) return;
clearTimeout(tm); removeEventListener("message", hd); m.ok ? res(m.text) : rej(new Error(m.error || "fetch failed")); }
addEventListener("message", hd); parent.postMessage({ type: "PGV_FETCH", url: url }, "*");
});
}
if (window.parent && window.parent !== window) {
addEventListener("message", function (ev) {
var m = ev.data; if (!m || typeof m !== "object" || m.type !== "PGV_INIT") return;
var p = m.payload || {}, url = (p.targets && p.targets.xml) || (p.repoLink + "/raw/branch/" + p.branch + "/" + p.path);
var bar = $("pgv"); bar.style.display = "block";
bar.textContent = "ProcessGit · " + (p.branch || "") + " · " + (p.path || "") + (p.lastCommit ? " · " + p.lastCommit.slice(0, 7) : "");
pgvFetch(url).then(show).catch(fail);
});
try { parent.postMessage({ type: "PGV_READY" }, "*"); } catch (e) {}
} else {
var f = new URLSearchParams(location.search).get("f");
if (f) fetch(f).then(function (r) { if (!r.ok) throw new Error("HTTP " + r.status); return r.text(); }).then(show).catch(fail);
else $("meta").textContent = "Atveriet sēdes datni ProcessGit (data/lv-mk-sede-….xml).";
}
})();
</script>
</body>
</html>