update
This commit is contained in:
@@ -87,7 +87,6 @@ const bandZiel = computed(() => {
|
||||
return ABSOLVIERT
|
||||
})
|
||||
const FORM_NAME = { quiz: 'Quiz', lueckentext: 'Lückentext', erklaeren: 'Erklären' }
|
||||
const NAECHSTES_FORMAT = { 6: 'Guide', 12: 'ProGuide', 18: 'FullGuide' }
|
||||
|
||||
// --- Toggle-Bereich ---
|
||||
const activeTab = ref(props.mode === 'full' ? props.initialTab : null) // null | 'chat' | 'pruefung'
|
||||
@@ -702,7 +701,7 @@ function onPruefKey(e) {
|
||||
<!-- Prüfung: gesteuerter Dialog -->
|
||||
<div v-else>
|
||||
<p class="bp-hint">
|
||||
<template v-if="amDeckel">{{ FORM_NAME[zeigeForm] }} · {{ score }}/{{ cap }} — <strong>Max</strong>.<template v-if="cap < VOLL"> Erstelle den {{ NAECHSTES_FORMAT[cap] }} für mehr.</template></template>
|
||||
<template v-if="amDeckel">{{ FORM_NAME[zeigeForm] }} · {{ score }}/{{ cap }} — <strong>Max</strong>.</template>
|
||||
<template v-else>{{ FORM_NAME[zeigeForm] }} · {{ score }}/{{ bandZiel }} · {{ modusRegel }}<span v-if="imZufall" class="bp-hint-key"> · zufällig</span></template>
|
||||
</p>
|
||||
<button
|
||||
|
||||
@@ -33,7 +33,7 @@ async function load() {
|
||||
}
|
||||
}
|
||||
|
||||
// Baustein relevant = hat ≥1 relevanten Subbaustein (gleiche Regel wie ProGuide).
|
||||
// Baustein relevant = hat ≥1 relevanten Subbaustein (gleiche Regel wie der Guide).
|
||||
// Ohne Relevanz-Daten (Alt-Themen) nicht dimmen.
|
||||
function relevant(b) {
|
||||
const mitRelevanz = (b.subbausteine || []).filter((s) => s.relevanz)
|
||||
@@ -70,7 +70,7 @@ const subTotal = computed(() => items.value.reduce((n, b) => n + (b.subbausteine
|
||||
:key="b.num"
|
||||
class="bk-card"
|
||||
:class="{ 'bk-irrelevant': !relevant(b) }"
|
||||
:title="relevant(b) ? null : 'Nicht relevant — nur im FullGuide'"
|
||||
:title="relevant(b) ? null : 'Nicht relevant — kommt später in den „Rest“'"
|
||||
>
|
||||
<h3 class="bk-title"><span class="bk-num">{{ b.num }}</span>{{ b.titel }}</h3>
|
||||
<p v-if="b.beschreibung" class="bk-desc">{{ b.beschreibung }}</p>
|
||||
@@ -79,7 +79,7 @@ const subTotal = computed(() => items.value.reduce((n, b) => n + (b.subbausteine
|
||||
<span class="bk-stufe-label">{{ g.label }}</span>
|
||||
<ul>
|
||||
<li v-for="s in g.subs" :key="s.titel" :class="{ rand: s.relevanz === 'rand' }">
|
||||
{{ s.titel }}<span v-if="s.relevanz === 'rand'" class="rand-tag" title="Randthema — nur im FullGuide">Rand</span>
|
||||
{{ s.titel }}<span v-if="s.relevanz === 'rand'" class="rand-tag" title="Randthema — kommt später in den „Rest“">Rand</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -122,12 +122,16 @@ watch(() => props.graph, build, { immediate: true })
|
||||
background: var(--panel, #fff);
|
||||
color: var(--text, #111);
|
||||
font-size: 0.8rem;
|
||||
line-height: 1.3;
|
||||
line-height: 1.35;
|
||||
text-align: center;
|
||||
max-width: 240px;
|
||||
max-width: 300px;
|
||||
/* Langer Text/Formel umbricht, statt im Knoten abgeschnitten zu werden. */
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
/* KaTeX im Knoten nicht umbrechen lassen */
|
||||
.gv-node :deep(.katex) { white-space: nowrap; }
|
||||
/* KaTeX im Knoten umbrechen lassen + geerbtes Klippen (markdown .katex-display) neutralisieren. */
|
||||
.gv-node :deep(.katex) { white-space: normal; }
|
||||
.gv-node :deep(.katex-display) { overflow: visible; margin: 0; }
|
||||
.graph-view :deep(.vue-flow__edge-text) { font-size: 0.72rem; fill: var(--text-muted, #666); }
|
||||
.graph-view :deep(.vue-flow__edge-textbg) { fill: var(--panel, #fff); }
|
||||
</style>
|
||||
|
||||
@@ -93,14 +93,8 @@ const fortschritt = computed(() => {
|
||||
return { total: bausteine.value.length, absolviert: a, verstanden: v, gemeistert: g }
|
||||
})
|
||||
|
||||
// Score-Deckel folgt dem höchsten erstellten Format: Mini→6, Guide→12, ProGuide→18, FullGuide→30.
|
||||
const cap = computed(() => {
|
||||
const d = props.doneByFormat || {}
|
||||
if (d.FullGuide) return 30
|
||||
if (d.ProGuide) return 18
|
||||
if (d.Guide) return 12
|
||||
return 6
|
||||
})
|
||||
// Ein Format „Guide" → Prüfung läuft voll 0–30. Ohne fertigen Guide kein Deckel relevant (6).
|
||||
const cap = computed(() => (props.doneByFormat?.Guide ? 30 : 6))
|
||||
|
||||
// --- Chat (Mechanik in useChat; Kontext-Extraktion bleibt hier) ---
|
||||
const chat = useChat((msgs) => {
|
||||
@@ -188,7 +182,7 @@ function extractContext() {
|
||||
<header class="guide-head">
|
||||
<h1>{{ previewGuide.topic }}</h1>
|
||||
<span class="guide-format">{{ previewGuide.format }}</span>
|
||||
<span v-if="themaAbgeschlossen" class="thema-done" title="Alle FullGuide-Bausteine gemeistert (25/25)">✓ Thema abgeschlossen</span>
|
||||
<span v-if="themaAbgeschlossen" class="thema-done" title="Alle Bausteine gemeistert (18/18)">✓ Thema abgeschlossen</span>
|
||||
</header>
|
||||
<section
|
||||
v-for="(ch, ci) in content.chapters"
|
||||
|
||||
@@ -47,19 +47,13 @@ const trackerItems = computed(() => {
|
||||
const fmt = (k) => `${f[k]?.absolviert ?? 0}/${f[k]?.erstellt ?? 0}`
|
||||
return [
|
||||
{ label: 'Themen', value: String(props.stats.themen ?? 0), title: 'Themen inkl. Projekte' },
|
||||
{ label: 'MiniGuides', value: fmt('MiniGuide'), title: 'absolviert/erstellt' },
|
||||
{ label: 'Guides', value: fmt('Guide'), title: 'absolviert/erstellt' },
|
||||
{ label: 'ProGuides', value: fmt('ProGuide'), title: 'absolviert/erstellt' },
|
||||
{ label: 'FullGuides', value: fmt('FullGuide'), title: 'absolviert/erstellt' },
|
||||
]
|
||||
})
|
||||
|
||||
const formats = [
|
||||
{ key: 'OnePager', label: 'OnePager' },
|
||||
{ key: 'MiniGuide', label: 'MiniGuide' },
|
||||
{ key: 'Guide', label: 'Guide' },
|
||||
{ key: 'ProGuide', label: 'ProGuide' },
|
||||
{ key: 'FullGuide', label: 'FullGuide' },
|
||||
]
|
||||
|
||||
const bausteineState = computed(() => {
|
||||
|
||||
Reference in New Issue
Block a user