Beteiligte in die Projekteinstellungen, TODOs aus Protokoll, Bewegung
Beteiligten-Zuordnung verlagert: p.assign ist jetzt ein Stammdatum und nur noch in den Projekteinstellungen editierbar (planCycleAssign()). Wochenbericht und Projektboard zeigen sie nur noch an, mit Verweis dorthin (springZuEinstellungen()). cycleAssign() ist damit entfallen. Neu "TODOs aus Protokoll": ein externes Besprechungsprotokoll als PDF wird per KI eingelesen und daraus in einem zweiten KI-Schritt Aufgaben abgeleitet. Eigener Bereich in der Aufgaben-/GANTT-Leiste, bewusst unabhaengig von den gespeicherten Protokollen - nichts davon wird abgelegt. Drei Schritte in einem Dialog mit fester Fusszeile; die Vorschlagsliste als kompakte, aufklappbare Zeilen, weil ein echter Import leicht 20 Vorschlaege liefert. Sichtbarkeit je Aufgabe im GANTT: neue Spalte plan_todos.show_in_gantt (Vorgabe 1, idempotente Migration) und eine Checkbox im Aufgaben-Dialog. Eine terminierte Aufgabe kann damit gezielt aus dem Terminplan herausgehalten werden, bleibt sonst aber eine vollwertige Aufgabe. plan-build-gantt.js und plan-drag.js pruefen dieselbe Bedingung, damit Zeilenzahl und Umsortierung nicht auseinanderlaufen. KI-Timeout dritte Stufe: ein abweichender, aber entfernter Endpunkt (Drittanbieter-Proxy) bekommt 2 Minuten statt der 45 Sekunden der echten Anbieter-API. Gemessen: die Punkte-Erkennung eines realen Protokolls brauchte dort 39 Sekunden, lag also stets knapp unter dem alten Limit und brach bei jeder Schwankung ab. Bewegung: Hover- und Klick-Rueckmeldung als Token-Satz in :root, angewandt auf die anklickbaren Zeilen, Schalter und Dialoge. Die Akzentleiste ist ein inset-Schatten statt eines positionierten Elements, damit Drag-and-Drop unberuehrt bleibt; prefers-reduced-motion war bisher gar nicht vorhanden und kippt jetzt einfach die Tokens. Plan Checker: optionaler Projektabgleich des Plankopfs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6ba93b2a92
commit
93505e0e48
17 files changed
+1883
-334
No files matched your search
@@ -7,7 +7,11 @@
|
||||
// admin-gepflegte Liste von Merkmalen prüfen (z. B. "Maßketten vorhanden",
|
||||
// siehe Admin → Plan-Checker-Merkmale, js/admin/admin.js). Zusätzlich lässt
|
||||
// sich je Prüfung EIN weiteres Merkmal ergänzen, das nur für diese eine
|
||||
// Prüfung gilt und nicht gespeichert wird.
|
||||
// Prüfung gilt und nicht gespeichert wird - und optional ein Projekt der
|
||||
// aktuellen Sitzung wählen: Dann kommt serverseitig automatisch ein
|
||||
// weiteres, ebenso nicht gespeichertes Merkmal dazu, das den Plankopf gegen
|
||||
// Projektnummer/Bezeichnung dieses Projekts abgleicht (ladePlanCheckerProjekte()/
|
||||
// planCheckerPruefen() unten, server.js POST /plan-checker-pruefen).
|
||||
//
|
||||
// Darstellung "Arbeitsfläche" (Eriks Wahl "B" aus dem Design-Vergleich):
|
||||
// zwei Spalten dauerhaft nebeneinander — links Upload/Konfiguration, rechts
|
||||
@@ -41,13 +45,42 @@ let planCheckerDatei = null;
|
||||
let planCheckerMerkmale = [];
|
||||
|
||||
// renderPlanChecker: Einstiegspunkt, von showTab('planchecker') gerufen.
|
||||
// Lädt die Merkmale-Grundliste und die KI-Anbieter-Auswahl neu — beide
|
||||
// können sich seit dem letzten Besuch geändert haben (Admin-Pflege bzw.
|
||||
// eigener Schlüssel unter Einstellungen → Mein Konto). Keine Parameter,
|
||||
// keine Rückgabe.
|
||||
// Lädt die Merkmale-Grundliste, die KI-Anbieter-Auswahl und die Projektliste
|
||||
// neu — alle drei können sich seit dem letzten Besuch geändert haben
|
||||
// (Admin-Pflege, eigener Schlüssel unter Einstellungen → Mein Konto, bzw.
|
||||
// ein inzwischen angelegtes/umbenanntes Projekt). Keine Parameter, keine
|
||||
// Rückgabe.
|
||||
function renderPlanChecker(){
|
||||
ladePlanCheckerMerkmale();
|
||||
ladePlanCheckerAnbieter();
|
||||
ladePlanCheckerProjekte();
|
||||
}
|
||||
|
||||
// ladePlanCheckerProjekte: füllt die optionale Projekt-Auswahl aus der
|
||||
// bereits geladenen aktuellen Sitzung (currentWeek().projects, js/weeks.js)
|
||||
// — kein eigener Server-Aufruf nötig, die Liste liegt dem Client ohnehin
|
||||
// schon vor. Gruppiert wie die Projektliste selbst (GROUP_ORDER/sortGroups(),
|
||||
// js/globals.js bzw. js/utils.js). Der Options-Wert ist die Projekt-ID
|
||||
// (stabil innerhalb der Sitzung) statt Nummer/Name direkt zu kodieren — bei
|
||||
// der Prüfung wird das Projekt darüber erneut in currentWeek().projects
|
||||
// nachgeschlagen (planCheckerPruefen() unten). Keine Parameter, keine
|
||||
// Rückgabe.
|
||||
function ladePlanCheckerProjekte(){
|
||||
const sel = document.getElementById('planCheckerProjekt');
|
||||
if(!sel) return;
|
||||
const w = typeof currentWeek === 'function' ? currentWeek() : null;
|
||||
const projekte = (w && Array.isArray(w.projects)) ? w.projects : [];
|
||||
const bisher = sel.value;
|
||||
const gruppenNamen = sortGroups([...new Set(projekte.map(p => p.group || 'Ohne Gruppe'))]);
|
||||
sel.innerHTML = '<option value="">Kein Projekt wählen</option>' + gruppenNamen.map(g => {
|
||||
const opts = projekte.filter(p => (p.group || 'Ohne Gruppe') === g)
|
||||
.slice().sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map(p => `<option value="${esc(p.id)}">${esc(p.nr ? p.nr + ' · ' : '')}${esc(p.name)}</option>`).join('');
|
||||
return opts ? `<optgroup label="${esc(g)}">${opts}</optgroup>` : '';
|
||||
}).join('');
|
||||
// Auswahl erhalten, falls sie nach dem Neuladen noch existiert (z. B. nach
|
||||
// erneutem Tab-Wechsel innerhalb derselben Sitzung).
|
||||
if(bisher && [...sel.options].some(o => o.value === bisher)) sel.value = bisher;
|
||||
}
|
||||
|
||||
// ladePlanCheckerMerkmale: holt die admin-gepflegte Grundliste (GET
|
||||
@@ -143,7 +176,7 @@ function planCheckerDrop(e){
|
||||
function planCheckerLadezustand(aktiv){
|
||||
const btn = document.getElementById('planCheckerPruefenBtn');
|
||||
if(btn){ btn.disabled = aktiv; btn.textContent = aktiv ? 'Wird geprüft…' : 'Plan prüfen'; }
|
||||
['planCheckerFile', 'planCheckerZusatz', 'planCheckerAnbieter'].forEach(id => {
|
||||
['planCheckerFile', 'planCheckerZusatz', 'planCheckerAnbieter', 'planCheckerProjekt'].forEach(id => {
|
||||
const el = document.getElementById(id);
|
||||
if(el) el.disabled = aktiv;
|
||||
});
|
||||
@@ -164,9 +197,20 @@ function planCheckerPruefen(){
|
||||
const zusatzEl = document.getElementById('planCheckerZusatz');
|
||||
const zusatz = zusatzEl ? zusatzEl.value.trim() : '';
|
||||
|
||||
// Projekt-Abgleich: die Auswahl trägt nur die Projekt-ID (s.
|
||||
// ladePlanCheckerProjekte() oben) - Nummer/Bezeichnung werden hier erneut
|
||||
// aus currentWeek().projects nachgeschlagen, statt sie schon beim Aufbau
|
||||
// der Auswahl im value zu kodieren.
|
||||
const projektEl = document.getElementById('planCheckerProjekt');
|
||||
const projektId = projektEl ? projektEl.value : '';
|
||||
const w = typeof currentWeek === 'function' ? currentWeek() : null;
|
||||
const projekt = projektId && w ? (w.projects || []).find(p => p.id === projektId) : null;
|
||||
|
||||
const url = baseUrl() + '/plan-checker-pruefen'
|
||||
+ '?provider=' + encodeURIComponent(provider)
|
||||
+ '&zusatzMerkmal=' + encodeURIComponent(zusatz);
|
||||
+ '&zusatzMerkmal=' + encodeURIComponent(zusatz)
|
||||
+ '&projektNr=' + encodeURIComponent(projekt ? (projekt.nr || '') : '')
|
||||
+ '&projektName=' + encodeURIComponent(projekt ? projekt.name : '');
|
||||
|
||||
const datei = planCheckerDatei;
|
||||
planCheckerLadezustand(true);
|
||||
|
||||
Reference in new issue
Block a user