This commit is contained in:
team3
2026-07-27 16:43:11 +02:00
parent 23c908534f
commit 7912eae715
14 changed files with 596 additions and 27 deletions

View File

@@ -87,7 +87,10 @@ onMounted(async () => {
@umbenannt="umbenannt"
>
<span v-if="aktivesProjekt" class="pruefen">
<button class="icon-knopf" title="Karten prüfen" @click="startePruefung(aktivesProjekt)">⌾</button>
<span class="knoepfe">
<button class="icon-knopf" title="Stil prüfen" @click="startePruefung(aktivesProjekt, 'stil')">⌾</button>
<button class="icon-knopf" title="Mit Code abgleichen" @click="startePruefung(aktivesProjekt, 'inhalt')">⌗</button>
</span>
<span v-if="pruefungLaeuft" class="fortschritt">{{ pruefungProzent }} %</span>
</span>
<button class="icon-knopf" :title="TITEL[modus]" @click="wechsleDarkMode">
@@ -137,13 +140,14 @@ main {
margin-top: 3rem;
text-align: center;
}
/* Fortschritt sitzt unter dem Prüf-Icon */
/* Fortschritt sitzt unter den Prüf-Icons */
.pruefen {
display: inline-flex;
flex-direction: column;
align-items: center;
line-height: 1.1;
}
.pruefen .knoepfe { display: flex; }
.fortschritt {
font-size: 0.65rem;
color: var(--dezent);

View File

@@ -41,8 +41,8 @@ export const featureSpeichern = (projekt, id, roh) =>
export const featureLoeschen = (projekt, id) =>
req(`/projekte/${p(projekt)}/features/${p(id)}`, { method: 'DELETE' })
export const pruefungStarten = (projekt) =>
req(`/projekte/${p(projekt)}/pruefung`, { method: 'POST' })
export const pruefungStarten = (projekt, art = 'stil') =>
req(`/projekte/${p(projekt)}/pruefung`, { method: 'POST', body: { art } })
export const fetchPruefung = (projekt) => req(`/projekte/${p(projekt)}/pruefung`)
export const pruefungBeenden = (projekt) =>
req(`/projekte/${p(projekt)}/pruefung`, { method: 'DELETE' })

View File

@@ -234,6 +234,18 @@ function anwenden(p) {
} else if (p.feld === 'badge') {
if (p.vorschlag !== 'kern' && p.vorschlag !== 'optional') return false
ziel.art = p.vorschlag
} else if (p.feld === 'funktionen') {
// Inhaltsprüfung: Einträge kommen dazu oder fallen weg. Bestehende Funktionen
// behalten dabei Ziel, Regeln und Testen — nur die Liste ändert sich.
const alt = s.value.funktionen
const titel = alt.map(f => f.text).join('\n')
const neu = p.ganzes_feld
? vorschlagsZeilen(p)
: (zeileAendern(titel, p) ?? '').split('\n').map(z => z.trim()).filter(Boolean)
if (p.ganzes_feld ? !neu.length : zeileAendern(titel, p) === null) return false
const bekannt = new Map(alt.map(f => [f.text, f]))
s.value.funktionen = neu.map(
t => bekannt.get(t) || { text: t, ziel: '', regeln: '', testen: '' })
} else if (p.feld === 'regeln' || p.feld === 'testen') {
if (typeof ziel[p.feld] !== 'string') return false // z. B. testen auf Kartenebene
if (p.ganzes_feld) {
@@ -363,8 +375,10 @@ function alleAblehnen() {
<p v-else-if="gross" class="hinweis" @click="starte('regeln')">Regeln ergänzen…</p>
</section>
<section :class="{ leer: !s.funktionen.length }">
<section :class="{ leer: !s.funktionen.length && !problemeFeld('funktionen').length }">
<p class="gruppe">Funktionen</p>
<ProblemHinweis :probleme="problemeFeld('funktionen')" @annehmen="annehmen" @ablehnen="ablehnen" />
<ProblemHinweis :probleme="problemeAn('funktionen')" @annehmen="annehmen" @ablehnen="ablehnen" />
<div class="liste">
<div
v-for="(f, i) in s.funktionen"

View File

@@ -1,5 +1,7 @@
<script setup>
import { laeuft, prozent, fertig, gesamt, meldung, probleme, schliesse } from '../composables/pruefung.js'
import { art, laeuft, prozent, fertig, gesamt, meldung, probleme, schliesse } from '../composables/pruefung.js'
const UEBERSCHRIFT = { stil: 'Stilprüfung', inhalt: 'Abgleich mit Code' }
// Nur die erste Zeile — mehrzeilige Stellen liefen hier sonst zu einem Klumpen zusammen
function erste(text) {
@@ -21,7 +23,7 @@ function springe(p) {
<template>
<aside class="panel">
<header>
<p class="gruppe">Prüfung</p>
<p class="gruppe">{{ UEBERSCHRIFT[art] || 'Prüfung' }}</p>
<button class="icon-knopf" title="Schließen" @click="schliesse">✕</button>
</header>

View File

@@ -8,6 +8,7 @@ export const laeuft = ref(false)
export const fertig = ref(0)
export const gesamt = ref(0)
export const meldung = ref('')
export const art = ref('stil')
export const probleme = ref([])
const gesehen = new Set() // schon übernommene Probleme holt der nächste Abruf nicht erneut
@@ -76,6 +77,7 @@ function uebernehmen(stand) {
fertig.value = stand.fertig
gesamt.value = stand.gesamt
meldung.value = stand.meldung
if (stand.art) art.value = stand.art
for (const p of stand.probleme) {
const k = schluessel(p)
if (gesehen.has(k)) continue
@@ -107,14 +109,15 @@ function stoppeUhr() {
uhr = null
}
export async function starte(projekt) {
export async function starte(projekt, pruefart = 'stil') {
projektName = projekt
art.value = pruefart
offen.value = true
meldung.value = ''
gesehen.clear()
probleme.value = []
try {
uebernehmen(await pruefungStarten(projekt))
uebernehmen(await pruefungStarten(projekt, pruefart))
} catch (e) {
if (e.status !== 409) { // 409 = Lauf läuft schon; dann daran anhängen
meldung.value = e.message