Plan Checker, Wochenbericht-Fokus-Modus und Wandtafel-Dashboard-Feinschliff
Plan Checker (neues Studenten-Werkzeug, Seitenleiste + Admin → Plan-Checker- Merkmale): lädt einen Bauplan als PDF hoch und lässt ChatGPT oder Claude ihn gegen eine gepflegte Merkmalsliste prüfen. PDF-Rendering (pdf.js + @napi-rs/canvas) berücksichtigt jetzt Ebenen (Optional Content Groups) und WASM-Decoder korrekt, sendet eine Übersicht plus mehrere hochaufgelöste Kachel-Ausschnitte statt eines einzelnen, zu groben Bilds, und beide Anbieter bekommen dasselbe Bildmaterial. Jedes Prüfergebnis kann auf eines der gesendeten Bilder als Beleg verweisen (bildIndex) — als Screenshot im Ergebnis anklickbar, öffnet vergrößert in einem Modal statt eines von Chrome blockierten target=_blank-Links auf eine data:-URL. KI-Modellname ist jetzt pro Konto überschreibbar (Einstellungen → Mein Konto) für Drittanbieter mit abweichendem Modell-Katalog. Wochenbericht: dichte Kartenansicht bekommt einen Fokus-Modus — nur der Kommentar liegt offen, Leistungsphasen und Beteiligte stecken in aufklappbaren Abschnitten statt dauerhaft nebeneinander zu stehen. Projektbereich: Terminplan-Auslastung rechnet jetzt exakt wie der Auslastungs-Tab/die Wandtafel (statt einer unabhängigen, tageweisen Schätzung); die LPH-Fortschrittsliste im Dashboard zeigt nur noch die beauftragten Leistungsphasen. Wandtafel: Dashboard-Kopf mit Kennzahlen-Reihe und Panel-Reihe neu strukturiert, in den Blautönen des Firmenlogos; dieselbe Palette wurde anschließend auf den gesamten App-weiten Dark Mode übernommen. Dateibereinigung: nicht mehr benötigte Test-Uploads/Backups entfernt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
db63a29365
commit
6ba93b2a92
308 files changed
+64441
-743
No files matched your search
@@ -139,6 +139,7 @@ function setAiMode(provider, modus){
|
||||
async function renderSettingsAiKeys(){
|
||||
const statusEl = { chatgpt: document.getElementById('aiOpenaiStatus'), claude: document.getElementById('aiClaudeStatus') };
|
||||
const urlEl = { chatgpt: document.getElementById('setAiOpenaiUrl'), claude: document.getElementById('setAiClaudeUrl') };
|
||||
const modelEl = { chatgpt: document.getElementById('setAiOpenaiModel'), claude: document.getElementById('setAiClaudeModel') };
|
||||
const clearBtn = { chatgpt: document.getElementById('aiOpenaiClearBtn'), claude: document.getElementById('aiClaudeClearBtn') };
|
||||
const reconnectBtn = { chatgpt: document.getElementById('aiOpenaiReconnectBtn'), claude: document.getElementById('aiClaudeReconnectBtn') };
|
||||
const testErrorEl = { chatgpt: document.getElementById('aiOpenaiTestError'), claude: document.getElementById('aiClaudeTestError') };
|
||||
@@ -156,6 +157,7 @@ async function renderSettingsAiKeys(){
|
||||
chip.innerHTML = '<span class="dot"></span>' + (info.configured ? 'Verbunden' : 'Nicht eingerichtet');
|
||||
}
|
||||
if(urlEl[provider] && document.activeElement !== urlEl[provider]) urlEl[provider].value = info.apiUrl || '';
|
||||
if(modelEl[provider] && document.activeElement !== modelEl[provider]) modelEl[provider].value = info.model || '';
|
||||
if(clearBtn[provider]) clearBtn[provider].disabled = !info.configured;
|
||||
if(reconnectBtn[provider]) reconnectBtn[provider].disabled = !info.configured;
|
||||
// Ein neuer Seitenaufruf ist ein neuer Anlauf — ein Fehler aus einem
|
||||
@@ -270,6 +272,32 @@ async function saveMyAiUrl(provider){
|
||||
}
|
||||
}
|
||||
|
||||
// saveMyAiModell: übernimmt den eingegebenen Modellnamen — leer löscht eine
|
||||
// zuvor gesetzte Abweichung und fällt auf die im Code hinterlegte Vorgabe
|
||||
// zurück (gpt-4o-mini/gpt-4o bzw. claude-haiku/claude-sonnet-5, je nach
|
||||
// Aufrufer). Nötig für einen eigenständigen Anbieter mit abweichendem
|
||||
// Modell-Katalog (z. B. Mammouth.ai), bei dem die festen OpenAI-/
|
||||
// Anthropic-Modellnamen nicht existieren. Eigenständig von saveMyAiUrl() aus
|
||||
// demselben Grund, aus dem URL und Schlüssel schon getrennte Speichern-
|
||||
// Knöpfe haben. Parameter: provider. Keine Rückgabe.
|
||||
async function saveMyAiModell(provider){
|
||||
const errEl = document.getElementById('settingsAiError');
|
||||
const show = msg => { if(errEl){ errEl.textContent = msg; errEl.hidden = false; } };
|
||||
if(errEl){ errEl.textContent = ''; errEl.hidden = true; }
|
||||
|
||||
const modelEl = document.getElementById(provider === 'chatgpt' ? 'setAiOpenaiModel' : 'setAiClaudeModel');
|
||||
const modelValue = modelEl ? modelEl.value.trim() : '';
|
||||
|
||||
try {
|
||||
await putMyAiKey(provider, { model: modelValue });
|
||||
renderSettingsAiKeys();
|
||||
showSettingsNote(modelValue ? 'Modellname gespeichert.' : 'Modellname entfernt — Vorgabe wird wieder verwendet.');
|
||||
} catch(err){
|
||||
console.error('Modellname speichern fehlgeschlagen:', err);
|
||||
show(err.message || String(err));
|
||||
}
|
||||
}
|
||||
|
||||
// clearMyAiKey: löscht nur den Schlüssel, lässt eine hinterlegte API-URL
|
||||
// unangetastet (patch enthält absichtlich kein apiUrl-Feld). Parameter:
|
||||
// provider. Keine Rückgabe.
|
||||
|
||||
Reference in new issue
Block a user