This commit is contained in:
Team3
2026-06-06 02:26:42 +02:00
parent a8fbf83059
commit 18bb18bf4a
30 changed files with 1184 additions and 4880 deletions

View File

@@ -8,13 +8,15 @@ const props = defineProps({
doneByFormat: { type: Object, default: () => ({}) },
latestByFormat: { type: Object, default: () => ({}) },
allGuides: { type: Array, default: () => [] },
bausteine: { type: Object, default: () => ({ ready: false, generating: false, progress: null, error: null }) },
activeBausteine: { type: Array, default: () => [] },
pinned: { type: Boolean, default: true },
dark: { type: Boolean, default: false },
provider: { type: String, default: 'claude' },
providers: { type: Array, default: () => [] },
})
const emit = defineEmits(['select', 'create', 'formatClick', 'deleteTopic', 'deleteProject', 'cancelGuide', 'deleteGuide', 'preview', 'togglePin', 'sidebarLeave', 'toggleDark', 'setProvider'])
const emit = defineEmits(['select', 'create', 'formatClick', 'bausteineClick', 'deleteTopic', 'deleteProject', 'cancelGuide', 'deleteGuide', 'preview', 'togglePin', 'sidebarLeave', 'toggleDark', 'setProvider'])
function providerAvailable(id) {
const p = props.providers.find((x) => x.id === id)
@@ -27,14 +29,34 @@ const formats = [
{ key: 'OnePager', label: 'OnePager' },
{ key: 'MiniGuide', label: 'MiniGuide' },
{ key: 'Guide', label: 'Guide' },
{ key: 'FullGuide', label: 'FullGuide' },
]
const BAUSTEINE_KEY = '__bausteine__'
const bausteineState = computed(() => {
if (props.bausteine.generating) return 'generating'
return props.bausteine.ready ? 'done' : 'none'
})
const activeGenerations = computed(() => {
return props.allGuides
const bausteinLines = props.activeBausteine.map(
(b) => `${b.topic} Bausteine: ${b.progress || 'Wartend…'}`,
)
const guideLines = props.allGuides
.filter((g) => g.status === 'generating' || g.status === 'queued')
.map((g) => `${g.topic} ${g.format}: ${g.progress || 'Wartend…'}`)
return [...bausteinLines, ...guideLines]
})
function handleBausteinePlay() {
if (bausteineState.value === 'generating') return
const text = activeInput.value === BAUSTEINE_KEY ? inputText.value.trim() : ''
emit('bausteineClick', { instructions: text })
activeInput.value = null
inputText.value = ''
}
function guideStatus(format) {
if (props.doneByFormat[format]) return 'done'
const latest = props.latestByFormat[format]
@@ -149,6 +171,36 @@ function confirmDeleteProject(name) {
<div class="progress-info" v-if="activeGenerations.length">
<div v-for="(line, i) in activeGenerations" :key="i">{{ line }}</div>
</div>
<div :class="['format-row', 'bausteine-row', 'fmt-' + bausteineState]">
<button class="format-name">
<span class="format-label">Bausteine</span>
</button>
<div class="format-actions">
<template v-if="bausteineState !== 'generating'">
<button
class="action-btn play"
:title="bausteine.ready ? 'Bausteine neu erstellen' : 'Bausteine erstellen'"
@click="handleBausteinePlay"
></button>
<button
class="action-btn pencil"
:class="{ active: activeInput === BAUSTEINE_KEY }"
title="Anweisungen"
@click="toggleInput(BAUSTEINE_KEY)"
></button>
</template>
</div>
</div>
<div v-if="bausteine.error" class="format-error">
<span class="format-error-text">{{ bausteine.error }}</span>
</div>
<div v-if="activeInput === BAUSTEINE_KEY" class="format-input">
<input
v-model="inputText"
placeholder="Anweisungen (optional)…"
@keyup.enter="handleBausteinePlay"
/>
</div>
<div v-for="f in formats" :key="f.key">
<div :class="['format-row', 'fmt-' + guideStatus(f.key)]">
<button class="format-name" @click="handleFormatClick(f.key)">
@@ -162,7 +214,12 @@ function confirmDeleteProject(name) {
</button>
<div class="format-actions">
<template v-if="guideStatus(f.key) !== 'generating' && guideStatus(f.key) !== 'queued'">
<button class="action-btn play" title="Generieren" @click="handlePlay(f.key)"></button>
<button
class="action-btn play"
:title="bausteine.ready ? 'Generieren' : 'Erst Bausteine erstellen'"
:disabled="!bausteine.ready"
@click="handlePlay(f.key)"
></button>
<button
class="action-btn pencil"
:class="{ active: activeInput === f.key }"
@@ -391,6 +448,15 @@ function confirmDeleteProject(name) {
}
/* Format section */
.format-row.bausteine-row {
margin-bottom: 0.5rem;
}
.action-btn:disabled {
opacity: 0.35;
cursor: not-allowed;
}
.format-section {
flex-shrink: 0;
max-height: 60vh;