update
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { ref, computed, watch, onMounted, nextTick } from 'vue'
|
||||
import { fetchGuides, fetchTopics, createTopic as apiCreateTopic, deleteTopic as apiDeleteTopic, createGuide as apiCreate, deleteGuide, cancelGuide as apiCancel, fetchBausteineStatus, fetchActiveBausteine, createBausteine as apiCreateBausteine, cancelBausteine as apiCancelBausteine, deleteBausteine as apiDeleteBausteine, fetchProviders, fetchStats, fetchTopicFortschritt, fetchGuideLocks, fetchFolders, updateQuelle as apiUpdateQuelle } from './api.js'
|
||||
import { fetchGuides, fetchTopics, createTopic as apiCreateTopic, deleteTopic as apiDeleteTopic, createGuide as apiCreate, deleteGuide, cancelGuide as apiCancel, fetchBausteineStatus, fetchActiveBausteine, createBausteine as apiCreateBausteine, cancelBausteine as apiCancelBausteine, deleteBausteine as apiDeleteBausteine, fetchProviders, fetchStats, fetchTopicFortschritt, fetchGuideLocks, fetchGuideSteps, fetchFolders, updateQuelle as apiUpdateQuelle } from './api.js'
|
||||
import { usePolling } from './composables/usePolling.js'
|
||||
import TopicSidebar from './components/TopicSidebar.vue'
|
||||
import TopicDetail from './components/TopicDetail.vue'
|
||||
@@ -30,6 +30,7 @@ const ansichtModus = ref('kompakt') // kompakt | erklärend — je
|
||||
const stats = ref(null)
|
||||
const fortschritt = ref({})
|
||||
const locks = ref({}) // Sperr-Gründe pro Format (Backend = einzige Regel-Quelle)
|
||||
const guideStepsDone = ref({}) // höchster fertiger Schritt-Index je Format (artefakt-basiert)
|
||||
const uiError = ref(null) // abgewiesene Aktionen (409/400) sichtbar machen
|
||||
const elementsOpen = ref(false) // rechte Sidebar
|
||||
const elementsView = ref(false) // Übersicht im Hauptbereich
|
||||
@@ -170,10 +171,12 @@ async function loadBausteine() {
|
||||
bausteine.value = await fetchBausteineStatus(selectedTopic.value)
|
||||
fortschritt.value = await fetchTopicFortschritt(selectedTopic.value)
|
||||
locks.value = await fetchGuideLocks(selectedTopic.value)
|
||||
guideStepsDone.value = await fetchGuideSteps(selectedTopic.value)
|
||||
} else {
|
||||
bausteine.value = { ...EMPTY_BAUSTEINE }
|
||||
fortschritt.value = {}
|
||||
locks.value = {}
|
||||
guideStepsDone.value = {}
|
||||
}
|
||||
if (activeBausteine.value.length && !polling.running()) startPolling()
|
||||
} catch (e) {
|
||||
@@ -380,6 +383,7 @@ onMounted(async () => {
|
||||
:stats="stats"
|
||||
:fortschritt="fortschritt"
|
||||
:locks="locks"
|
||||
:guideStepsDone="guideStepsDone"
|
||||
:uiError="uiError"
|
||||
:doneByFormat="doneByFormat"
|
||||
:latestByFormat="latestByFormat"
|
||||
|
||||
@@ -18,6 +18,11 @@ export async function fetchGuides() {
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function fetchGuideSteps(topic) {
|
||||
const res = await fetch(`${BASE}/guides/steps?topic=${encodeURIComponent(topic)}`)
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function fetchGuideLocks(topic) {
|
||||
const res = await fetch(`${BASE}/guides/locks?topic=${encodeURIComponent(topic)}`)
|
||||
return res.json()
|
||||
|
||||
@@ -9,6 +9,7 @@ const props = defineProps({
|
||||
stats: { type: Object, default: null },
|
||||
fortschritt: { type: Object, default: () => ({}) },
|
||||
locks: { type: Object, default: () => ({}) },
|
||||
guideStepsDone: { type: Object, default: () => ({}) }, // höchster fertiger Schritt je Format (-1 = keiner)
|
||||
uiError: { type: String, default: null },
|
||||
doneByFormat: { type: Object, default: () => ({}) },
|
||||
latestByFormat: { type: Object, default: () => ({}) },
|
||||
@@ -121,35 +122,26 @@ function guideStatus(format) {
|
||||
// Schritt-Kugeln der Guide-Pipeline
|
||||
const GUIDE_STEPS = ['Auswahl', 'Gliederung', 'Inhalte', 'Inhalts-Check', 'Schreiben', 'Lese-Prüfung']
|
||||
|
||||
// Kugeln werden wie bei den Bausteinen immer angezeigt:
|
||||
// fertig = alle grün, laufend = live, abgebrochen = Teilfortschritt, sonst grau
|
||||
// Kugeln aus dem artefakt-basierten „fertig"-Marker (wie Bausteine, nicht aus dem DB-Zähler):
|
||||
// ≤ fertig = done. Läuft gerade → der nächste Schritt (fertig+1) ist aktiv.
|
||||
function guideSteps(format) {
|
||||
const labels = GUIDE_STEPS
|
||||
const fertig = props.guideStepsDone[format] ?? -1
|
||||
const st = guideStatus(format)
|
||||
if (st === 'generating' || st === 'queued') {
|
||||
// Clamp: alte DB-Läufe können step-Werte oberhalb der neuen Listen haben
|
||||
const step = Math.min(props.latestByFormat[format]?.step ?? -1, labels.length - 1)
|
||||
return labels.map((label, i) => ({
|
||||
label,
|
||||
state: i < step ? 'done' : i === step ? 'active' : 'pending',
|
||||
}))
|
||||
}
|
||||
if (props.doneByFormat[format]) {
|
||||
return labels.map((label) => ({ label, state: 'done' }))
|
||||
}
|
||||
if (abgebrochen(format)) {
|
||||
const step = Math.min(props.latestByFormat[format]?.step ?? 0, labels.length)
|
||||
return labels.map((label, i) => ({ label, state: i < step ? 'done' : 'pending' }))
|
||||
}
|
||||
return labels.map((label) => ({ label, state: 'pending' }))
|
||||
const aktiv = st === 'generating' || st === 'queued' ? fertig + 1 : -1
|
||||
return labels.map((label, i) => ({
|
||||
label,
|
||||
state: i <= fertig ? 'done' : i === aktiv ? 'active' : 'pending',
|
||||
}))
|
||||
}
|
||||
|
||||
// Re-Run ab Guide-Schritt (1-basierte Kugel je Format). null = voll/Resume.
|
||||
const gewaehlterStep = reactive({})
|
||||
// Kugeln klickbar, sobald der Guide (teil-)gebaut ist und gerade nicht generiert wird.
|
||||
// Kugeln klickbar, sobald Artefakte existieren (Marker ≥ 0 oder fertig) und nicht generiert wird.
|
||||
function guideWaehlbar(format) {
|
||||
const st = guideStatus(format)
|
||||
return (st === 'done' || abgebrochen(format)) && st !== 'generating' && st !== 'queued'
|
||||
if (st === 'generating' || st === 'queued') return false
|
||||
return (props.guideStepsDone[format] ?? -1) >= 0 || st === 'done'
|
||||
}
|
||||
function guideStepKlick(format, n) {
|
||||
if (!guideWaehlbar(format)) return
|
||||
|
||||
Reference in New Issue
Block a user