Dashboard: - Neuer Endpoint GET /api/stats/dashboard mit allen Kennzahlen - Klickbare Kacheln: Vorlagen nach Typ, Ketten nach Status → navigieren zu Filterlisten - Umsetzungsquote als horizontaler Balken mit klickbaren Segmenten Abstimmungen: - Stimmverhalten-Tabelle klickbar: Fraktion oder Ja/Nein/Enthaltung → filtert - Neuer Endpoint GET /api/abstimmungen/details (?fraktion=&stimme=) mit Pagination - Neuer Endpoint GET /api/abstimmungen/vergleich (?f1=&f2=) für Koalitionsmatrix-Drill-Down - Koalitionsmatrix-Zellen klickbar → zeigt Abstimmungsvergleich beider Fraktionen Fraktions-Normalisierung: - fraktionen_mapping.py: 40+ DB-Varianten → kanonische Namen - 'Bündnis 90 / Die Grünen' / 'Bündnis 90/Die Grünen' / 'Grüne' → 'Grüne' - 'Die Linke' / 'Die Linke.' / 'Linke' → 'Linke' - BfHo-Varianten, Hagen Aktiv, Einzelvertreter etc. normalisiert - Mapping in allen Abstimmungs-Endpoints aktiv - ist_ratsfraktion Flag in Fraktionen-Response Closes #14
2 lines
11 KiB
JavaScript
2 lines
11 KiB
JavaScript
import{h as Ae,a as d,f as g,d as Je,b as ce,c as Be,t as Oe}from"../chunks/B89f14j0.js";import{o as Pe}from"../chunks/DrzKg1h1.js";import{p as Ee,h as r,r as t,b as s,g as e,t as p,c as Me,u as O,s as P,n as R,d as F,an as Re,H as Se,$ as We,f as ge}from"../chunks/reyx9_7L.js";import{s as i}from"../chunks/BwTTNG21.js";import{s as qe,a as Ce}from"../chunks/CvtDgobB.js";import{i as y}from"../chunks/Do7Yo2YN.js";import{h as Ge,e as Z,i as V}from"../chunks/D5EBvEcH.js";import{s as be}from"../chunks/B-WTs0fq.js";import{s as Qe}from"../chunks/C7sCDBjT.js";import{s as ae}from"../chunks/DnBxR3jh.js";import{b as Xe}from"../chunks/Be1Vm8i2.js";import{p as Ye}from"../chunks/wNiDNfGw.js";import{i as et}from"../chunks/nhOotKLT.js";import{p as Fe}from"../chunks/DfsAIpU3.js";import{f as Ke}from"../chunks/utcFFRIM.js";const fe={erfuellt:{label:"Erfüllt",farbe:"#22c55e",icon:"✅",beschreibung:"Forderung vollständig oder weitgehend umgesetzt. Konkreter Beschluss liegt vor, der die Kernpunkte des Antrags aufgreift.",beispiel:"Antrag auf Zuschuss → Zuschuss in beantragter Höhe einstimmig bewilligt.",score_range:[.8,1]},teilweise:{label:"Teilweise",farbe:"#eab308",icon:"⚠️",beschreibung:"Kernpunkt wurde adressiert, aber mit Abstrichen. Verwaltung greift Teile auf, lässt andere fallen oder verwässert die Forderung.",beispiel:"Antrag auf Radweg → Prüfauftrag für Machbarkeitsstudie statt direktem Baubeschluss.",score_range:[.5,.7]},abgewiegelt:{label:"Abgewiegelt",farbe:"#f97316",icon:"🚫",beschreibung:"Verwaltung weicht aus. Kündigt Prüfung an, verweist auf Zuständigkeiten oder beantwortet die Frage nicht substantiell.",beispiel:'Anfrage zu Missständen → „Wird geprüft" ohne Zeitrahmen oder konkrete Zusagen.',score_range:[.2,.4]},nebelkerze:{label:"Nebelkerze",farbe:"#ef4444",icon:"💨",beschreibung:"Thema komplett ignoriert, Diskussion auf Nebenschauplatz verlagert oder Antrag ohne Behandlung von der Tagesordnung genommen.",beispiel:'Antrag zu Sauberkeit → „Ohne Beschlussfassung" oder keine Wortmeldung.',score_range:[0,.1]},vertagt:{label:"Vertagt",farbe:"#8b5cf6",icon:"⏳",beschreibung:"Antrag explizit verschoben, ruhend gestellt oder in einen anderen Ausschuss verwiesen. Kein inhaltliches Ergebnis, aber formal nicht abgelehnt.",beispiel:"Antrag wird zur weiteren Beratung in den Fachausschuss überwiesen.",score_range:null},unklar:{label:"Unklar",farbe:"#6b7280",icon:"❓",beschreibung:"Beschlusslage nicht eindeutig zuordenbar. Möglicherweise fehlen Dokumente oder der Beschlusstext ist nicht aussagekräftig genug.",beispiel:'Nur „Kenntnisnahme" ohne weitere Erläuterung.',score_range:null}},Te={label:"Unbekannt",farbe:"#9ca3af",icon:"❓",beschreibung:"Keine Bewertung vorhanden.",beispiel:"",score_range:null};function tt(H){return H?fe[H]??Te:Te}var rt=g('<span class="ml-1 opacity-60"> </span>'),at=g('<div class="mt-1 text-gray-400"> </div>'),st=g('<div class="absolute z-50 bottom-full left-1/2 -translate-x-1/2 mb-2 w-72 p-3 bg-gray-900 text-white text-xs rounded-lg shadow-lg pointer-events-none"><div class="font-bold mb-1"> </div> <div class="mb-2 leading-relaxed"> </div> <div class="text-gray-400 italic"> </div> <!> <div class="absolute top-full left-1/2 -translate-x-1/2 -mt-1 w-2 h-2 bg-gray-900 rotate-45"></div></div>'),nt=g('<span class="relative inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium cursor-help"><span class="mr-1"> </span> <!> <!></span>');function De(H,L){Ee(L,!0);let S=Fe(L,"score",3,null),se=Fe(L,"showTooltip",3,!0);const m=O(()=>tt(L.kategorie));let o=P(!1);var $=nt(),E=r($),W=r(E,!0);t(E);var z=s(E),j=s(z);{var q=K=>{var T=rt(),M=r(T);t(T),p(Q=>i(M,`(${Q??""}%)`),[()=>(S()*100).toFixed(0)]),d(K,T)};y(j,K=>{S()!==null&&S()!==void 0&&K(q)})}var C=s(j,2);{var G=K=>{var T=st(),M=r(T),Q=r(M);t(M);var v=s(M,2),A=r(v,!0);t(v);var D=s(v,2),te=r(D);t(D);var re=s(D,2);{var X=Y=>{var I=at(),ne=r(I);t(I),p(()=>i(ne,`Score: ${e(m).score_range[0]??""}–${e(m).score_range[1]??""}`)),d(Y,I)};y(re,Y=>{e(m).score_range&&Y(X)})}R(2),t(T),p(()=>{i(Q,`${e(m).icon??""} ${e(m).label??""}`),i(A,e(m).beschreibung),i(te,`Beispiel: ${e(m).beispiel??""}`)}),d(K,T)};y(C,K=>{se()&&e(o)&&K(G)})}t($),p(()=>{ae($,`background-color: ${e(m).farbe??""}20; color: ${e(m).farbe??""}; border: 1px solid ${e(m).farbe??""}40;`),i(W,e(m).icon),i(z,` ${e(m).label??""} `)}),Ae("mouseenter",$,()=>F(o,!0)),Ae("mouseleave",$,()=>F(o,!1)),d(H,$),Me()}var it=g('<div class="text-gray-500">Laden...</div>'),lt=g('<div class="text-red-600"> </div>'),ot=g('<div class="bg-green-50 rounded-lg border border-green-200 p-4"><div class="text-2xl sm:text-3xl font-bold text-green-700"> </div> <div class="text-xs sm:text-sm text-green-600">Erfüllt</div></div>'),dt=g('<div class="bg-red-50 rounded-lg border border-red-200 p-4"><div class="text-2xl sm:text-3xl font-bold text-red-700"> </div> <div class="text-xs sm:text-sm text-red-600">Nebelkerzen</div></div>'),vt=g('<div class="flex items-center justify-center text-xs font-medium text-white transition-all"><!></div>'),ut=g('<button><span class="w-3 h-3 rounded-full inline-block shrink-0"></span> </button>'),ct=g('<div class="bg-white rounded-lg border p-4 sm:p-6 mb-8"><h2 class="font-bold mb-4">Umsetzungsquote</h2> <div class="flex rounded-full overflow-hidden h-8 mb-4"></div> <div class="flex flex-wrap gap-3 sm:gap-4 text-sm"></div></div>'),gt=g("<option> </option>"),bt=g('<button class="text-sm text-blue-600 hover:underline p-1">Filter zurücksetzen</button>'),ft=g('<span class="text-gray-400 text-xs">–</span>'),mt=g('<tr class="hover:bg-gray-50"><td class="px-4 py-3"><a class="text-blue-600 hover:underline font-mono text-xs"> </a></td><td class="px-4 py-3 max-w-md truncate"> </td><td class="px-4 py-3 text-gray-500 whitespace-nowrap"> </td><td class="px-4 py-3"><!></td></tr>'),pt=g('<a class="block bg-white rounded-lg border p-4 hover:shadow-md transition-shadow"><div class="flex items-start justify-between gap-2 mb-2"><span class="font-mono text-xs text-blue-600"> </span> <span class="text-xs text-gray-500 shrink-0"> </span></div> <div class="text-sm text-gray-700 line-clamp-2 mb-2"> </div> <!></a>'),xt=g('<div class="flex items-center gap-4 mb-6"><div class="w-3 h-12 rounded shrink-0"></div> <div class="min-w-0"><h1 class="text-2xl font-bold"> </h1> <span class="text-sm text-gray-500"> </span></div> <a href="/fraktionen" class="ml-auto text-sm text-blue-600 hover:underline shrink-0">← Alle Fraktionen</a></div> <div class="grid grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4 mb-8"><div class="bg-white rounded-lg border p-4"><div class="text-2xl sm:text-3xl font-bold"> </div> <div class="text-xs sm:text-sm text-gray-500">Anträge gesamt</div></div> <div class="bg-white rounded-lg border p-4"><div class="text-2xl sm:text-3xl font-bold"> </div> <div class="text-xs sm:text-sm text-gray-500">Mit Bewertung</div></div> <!> <!></div> <!> <div class="flex flex-wrap gap-3 sm:gap-4 mb-4 items-center"><select class="border rounded px-3 py-2 text-sm"><option>Alle Jahre</option><!></select> <!> <span class="text-sm text-gray-500 sm:ml-auto"> </span></div> <div class="hidden md:block bg-white rounded-lg border overflow-hidden"><table class="w-full text-sm"><thead class="bg-gray-50 text-left"><tr><th class="px-4 py-3 font-medium">Aktenzeichen</th><th class="px-4 py-3 font-medium">Betreff</th><th class="px-4 py-3 font-medium">Datum</th><th class="px-4 py-3 font-medium">Umsetzung</th></tr></thead><tbody class="divide-y"></tbody></table></div> <div class="md:hidden space-y-3"></div>',1),_t=g('<div class="max-w-6xl mx-auto"><!></div>');function Ut(H,L){Ee(L,!0);const S=()=>Ce(Ye,"$page",se),[se,m]=qe();let o=P(null),$=P(!0),E=P(null),W=P(""),z=P(""),j=O(()=>S().params.kuerzel);async function q(){F($,!0),F(E,null);try{F(o,await et(e(j),e(W)||void 0),!0)}catch(v){F(E,v.message,!0)}F($,!1)}Pe(q),Re(()=>{e(j)&&q()});let C=O(()=>e(o)?.antraege.filter(v=>!e(z)||v.umsetzung_bewertung===e(z))??[]);var G=_t();Ge("1jei61n",v=>{Se(()=>{We.title=`${e(o)?.partei?.name??e(j)??""} — Antragstracker Hagen`})});var K=r(G);{var T=v=>{var A=it();d(v,A)},M=v=>{var A=lt(),D=r(A);t(A),p(()=>i(D,`Fehler: ${e(E)??""}`)),d(v,A)},Q=v=>{var A=xt(),D=ge(A),te=r(D),re=s(te,2),X=r(re),Y=r(X,!0);t(X);var I=s(X,2),ne=r(I,!0);t(I),t(re),R(2),t(D);var ie=s(D,2),le=r(ie),me=r(le),Ne=r(me,!0);t(me),R(2),t(le);var oe=s(le,2),pe=r(oe),Ue=r(pe,!0);t(pe),R(2),t(oe);var xe=s(oe,2);Z(xe,17,()=>e(o).umsetzung.filter(l=>l.bewertung==="erfuellt"),V,(l,a)=>{var n=ot(),u=r(n),c=r(u,!0);t(u),R(2),t(n),p(()=>i(c,e(a).anzahl)),d(l,n)});var Ze=s(xe,2);Z(Ze,17,()=>e(o).umsetzung.filter(l=>l.bewertung==="nebelkerze"),V,(l,a)=>{var n=dt(),u=r(n),c=r(u,!0);t(u),R(2),t(n),p(()=>i(c,e(a).anzahl)),d(l,n)}),t(ie);var _e=s(ie,2);{var Ve=l=>{var a=ct(),n=s(r(a),2);Z(n,21,()=>e(o).umsetzung,V,(c,x)=>{const f=O(()=>fe[e(x).bewertung]),h=O(()=>e(x).anzahl/e(o).bewertet*100);var w=Be(),N=ge(w);{var B=_=>{var b=vt(),J=r(b);{var k=U=>{var $e=Oe();p(Ie=>i($e,`${e(f).label??""} ${Ie??""}%`),[()=>e(h).toFixed(0)]),d(U,$e)};y(J,U=>{e(h)>8&&U(k)})}t(b),p(U=>{ae(b,`width: ${e(h)??""}%; background-color: ${e(f).farbe??""};`),be(b,"title",`${e(f).label??""}: ${e(x).anzahl??""} (${U??""}%)`)},[()=>e(h).toFixed(1)]),d(_,b)};y(N,_=>{e(f)&&e(h)>0&&_(B)})}d(c,w)}),t(n);var u=s(n,2);Z(u,21,()=>e(o).umsetzung,V,(c,x)=>{const f=O(()=>fe[e(x).bewertung]);var h=Be(),w=ge(h);{var N=B=>{var _=ut();let b;var J=r(_),k=s(J);t(_),p(()=>{b=Qe(_,1,"flex items-center gap-1.5 hover:opacity-70 transition-opacity p-1",null,b,{"opacity-40":e(z)&&e(z)!==e(x).bewertung}),ae(J,`background-color: ${e(f).farbe??""}`),i(k,` ${e(f).label??""}: ${e(x).anzahl??""}`)}),ce("click",_,()=>F(z,e(z)===e(x).bewertung?"":e(x).bewertung,!0)),d(B,_)};y(w,B=>{e(f)&&B(N)})}d(c,h)}),t(u),t(a),d(l,a)};y(_e,l=>{e(o).bewertet>0&&l(Ve)})}var de=s(_e,2),ee=r(de),ve=r(ee);ve.value=ve.__value="";var He=s(ve);Z(He,17,()=>e(o).jahre,V,(l,a)=>{var n=gt(),u=r(n,!0);t(n);var c={};p(()=>{i(u,e(a)),c!==(c=e(a))&&(n.value=(n.__value=e(a))??"")}),d(l,n)}),t(ee);var he=s(ee,2);{var Le=l=>{var a=bt();ce("click",a,()=>F(z,"")),d(l,a)};y(he,l=>{e(z)&&l(Le)})}var we=s(he,2),je=r(we);t(we),t(de);var ue=s(de,2),ke=r(ue),ze=s(r(ke));Z(ze,21,()=>e(C),V,(l,a)=>{var n=mt(),u=r(n),c=r(u),x=r(c,!0);t(c),t(u);var f=s(u),h=r(f,!0);t(f);var w=s(f),N=r(w,!0);t(w);var B=s(w),_=r(B);{var b=k=>{De(k,{get kategorie(){return e(a).umsetzung_bewertung},get score(){return e(a).umsetzung_score}})},J=k=>{var U=ft();d(k,U)};y(_,k=>{e(a).umsetzung_bewertung?k(b):k(J,-1)})}t(B),t(n),p(k=>{be(c,"href",`/vorlagen/${e(a).id??""}`),i(x,e(a).aktenzeichen),i(h,e(a).betreff),i(N,k)},[()=>Ke(e(a).datum_eingang)]),d(l,n)}),t(ze),t(ke),t(ue);var ye=s(ue,2);Z(ye,21,()=>e(C),V,(l,a)=>{var n=pt(),u=r(n),c=r(u),x=r(c,!0);t(c);var f=s(c,2),h=r(f,!0);t(f),t(u);var w=s(u,2),N=r(w,!0);t(w);var B=s(w,2);{var _=b=>{De(b,{get kategorie(){return e(a).umsetzung_bewertung},get score(){return e(a).umsetzung_score}})};y(B,b=>{e(a).umsetzung_bewertung&&b(_)})}t(n),p(b=>{be(n,"href",`/vorlagen/${e(a).id??""}`),i(x,e(a).aktenzeichen),i(h,b),i(N,e(a).betreff)},[()=>Ke(e(a).datum_eingang)]),d(l,n)}),t(ye),p(()=>{ae(te,`background-color: ${(e(o).partei.farbe||"#6b7280")??""}`),i(Y,e(o).partei.name),i(ne,e(o).partei.kuerzel),i(Ne,e(o).total_antraege),i(Ue,e(o).bewertet),i(je,`${e(C).length??""} Anträge`)}),ce("change",ee,q),Xe(ee,()=>e(W),l=>F(W,l)),d(v,A)};y(K,v=>{e($)&&!e(o)?v(T):e(E)?v(M,1):e(o)&&v(Q,2)})}t(G),d(H,G),Me(),m()}Je(["click","change"]);export{Ut as component};
|