This commit is contained in:
team3
2026-07-06 17:32:52 +02:00
parent cc27e53b9e
commit 73ac3e532f
19 changed files with 565 additions and 523 deletions

View File

@@ -1,6 +1,6 @@
<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { fetchGuides, fetchTopics, deleteTopic as apiDeleteTopic, createGuide as apiCreate, deleteGuide, cancelGuide as apiCancel, fetchBlocksStatus, fetchActiveBlocks, createBlocks as apiCreateBausteine, resetBlocksStage as apiResetBlocksStage, addBlocksResearch as apiAddResearch, requeueBlocksDead as apiRequeueDead, resetGuideBoard as apiResetGuideBoard, restartBlocksCard as apiRestartBlocksCard, resetGuideCard as apiResetGuideCard, removeGuideFormat as apiRemoveGuideFormat, cancelBlocks as apiCancelBausteine, deleteBlocks as apiDeleteBausteine, fetchProviders, fetchStats, fetchTopicProgress, fetchFolders, updateSource as apiUpdateQuelle } from './api.js'
import { fetchGuides, fetchTopics, deleteTopic as apiDeleteTopic, createGuide as apiCreate, deleteGuide, cancelGuide as apiCancel, fetchBlocksStatus, fetchActiveBlocks, createBlocks as apiCreateBausteine, addBlocksResearch as apiAddResearch, requeueBlocksDead as apiRequeueDead, removeGuideFormat as apiRemoveGuideFormat, cancelBlocks as apiCancelBausteine, deleteBlocks as apiDeleteBausteine, fetchProviders, fetchStats, fetchTopicProgress, fetchFolders, updateSource as apiUpdateQuelle } from './api.js'
import { usePolling } from './composables/usePolling.js'
import TopicSidebar from './components/TopicSidebar.vue'
import TopicDetail from './components/TopicDetail.vue'
@@ -182,12 +182,31 @@ async function loadBlocks() {
}
}
// „Auto"-Ebenen-Flags pro Topic (localStorage): nach der QA „Befunde beheben" bis 100 %.
const autoInventory = ref(true)
const autoArtefacts = ref(true)
const autoGuide = ref(true)
function ladeAuto(topic) {
const g = (e) => { const v = localStorage.getItem(`auto_${topic}_${e}`); return v === null ? true : v === 'true' }
autoInventory.value = g('inventory')
autoArtefacts.value = g('artefacts')
autoGuide.value = g('guide')
}
function handleSetAuto({ ebene, value }) {
const r = { inventory: autoInventory, artefacts: autoArtefacts, guide: autoGuide }[ebene]
if (!r) return
r.value = value
if (selectedTopic.value) localStorage.setItem(`auto_${selectedTopic.value}_${ebene}`, value ? 'true' : 'false')
}
const autoObj = () => ({ inventory: autoInventory.value, artefacts: autoArtefacts.value, guide: autoGuide.value })
function selectTopic(topic) {
selectedTopic.value = topic
previewGuide.value = null
sidebarSticky.value = false
mainView.value = 'generation' // topic click → generation board (guide only on pill click)
viewMode.value = localStorage.getItem('ansicht_' + topic) === 'erklärend' ? 'erklärend' : 'compact'
ladeAuto(topic)
localStorage.setItem('lastTopic', topic)
loadBlocks()
}
@@ -207,20 +226,6 @@ async function handleResetBlocks() {
if (await withUiError(() => apiDeleteBausteine(selectedTopic.value))) await loadBlocks()
}
async function handleResetStage({ board, stage, restart = false }) {
if (!selectedTopic.value) return
uiError.value = null
try {
await apiResetBlocksStage(selectedTopic.value, board, stage)
if (restart) await apiCreateBausteine(selectedTopic.value, '', provider.value, undefined, undefined, false) // Continue: Queue abarbeiten
} catch (e) {
uiError.value = e.message
return
}
await loadBlocks()
if (restart) startPolling()
}
async function handleAddResearch() {
if (!selectedTopic.value) return
uiError.value = null
@@ -238,7 +243,7 @@ async function handleRequeueDead() {
if (!selectedTopic.value) return
const ok = await withUiError(async () => {
await apiRequeueDead(selectedTopic.value)
await apiCreateBausteine(selectedTopic.value, '', provider.value, undefined, undefined, false)
await apiCreateBausteine(selectedTopic.value, '', provider.value, undefined, undefined, false, false, autoObj())
})
if (!ok) return
await loadBlocks()
@@ -250,7 +255,7 @@ async function handleBlocksClick({ instructions = '', research = true, qaForce =
uiError.value = null
try {
// research=true = Start/mehr Research anhängen; false = Continue (Queue abarbeiten).
await apiCreateBausteine(selectedTopic.value, instructions, provider.value, undefined, undefined, research, qaForce)
await apiCreateBausteine(selectedTopic.value, instructions, provider.value, undefined, undefined, research, qaForce, autoObj())
} catch (e) {
uiError.value = e.message
return
@@ -300,7 +305,7 @@ function handleOpenBlocksView() {
previewGuide.value = null
}
async function handleFormatClick({ format, instructions = '', abStep = null }) {
async function handleFormatClick({ format, instructions = '' }) {
if (!selectedTopic.value) return
// No duplicate start: if a generation is already running for topic+format, ignore
const running = guides.value.some(
@@ -310,7 +315,7 @@ async function handleFormatClick({ format, instructions = '', abStep = null }) {
if (running) { handleOpenGuideBoard(format); return }
uiError.value = null
try {
await apiCreate(selectedTopic.value, format, instructions, provider.value, abStep)
await apiCreate(selectedTopic.value, format, instructions, provider.value)
} catch (e) {
uiError.value = e.message
return
@@ -344,34 +349,6 @@ async function handleRemoveGuideFormat(format) {
await loadGuides()
}
async function handleRestartCard(cardId) {
uiError.value = null
try {
await apiRestartBlocksCard(selectedTopic.value, cardId)
await handleBlocksClick({ research: false }) // Continue: der Flow zieht die Karte
} catch (e) {
uiError.value = e.message
}
}
async function handleResetGuideCard({ format, blockNorm, abStage }) {
uiError.value = null
try {
await apiResetGuideCard(selectedTopic.value, format, blockNorm, abStage)
} catch (e) {
uiError.value = e.message
}
}
async function handleGuideBoardReset({ format, abStage }) {
uiError.value = null
try {
await apiResetGuideBoard(selectedTopic.value, format, abStage)
} catch (e) {
uiError.value = e.message
}
}
function handleGuideBoardPreview() {
const g = doneByFormat.value[guideBoardFormat.value]
if (g) handlePreview(g)
@@ -502,8 +479,10 @@ onMounted(async () => {
:partial="blocks.partial"
:error="blocks.error"
:guideFormat="guideBoardFormat"
:autoInventory="autoInventory"
:autoArtefacts="autoArtefacts"
:autoGuide="autoGuide"
@close="mainView = 'blocks'"
@resetStage="handleResetStage"
@restartAll="() => handleBlocksClick({ research: true })"
@continueAll="(opts) => handleBlocksClick({ research: false, qaForce: !!(opts && opts.qaForce) })"
@addResearch="handleAddResearch"
@@ -512,11 +491,9 @@ onMounted(async () => {
@cancel="handleCancelBlocks"
@cancelGuide="handleCancel"
@startGuide="handleFormatClick"
@resetGuideStage="handleGuideBoardReset"
@preview="handleGuideBoardPreview"
@removeFormat="handleRemoveGuideFormat"
@restartCard="handleRestartCard"
@resetGuideCard="handleResetGuideCard"
@setAuto="handleSetAuto"
/>
<GeneralExamPanel
v-else-if="selectedTopic && mainView === 'general'"