This commit is contained in:
Team3
2026-05-29 17:58:43 +02:00
parent a826e9f6b3
commit 067d7229de
8 changed files with 183 additions and 14 deletions

View File

@@ -70,6 +70,19 @@ export async function reworkBaustein(id, instructions) {
})
}
export async function sortBausteine(topic, instructions = '') {
await fetch(`${BASE}/bausteine/sort?topic=${encodeURIComponent(topic)}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ instructions }),
})
}
export async function fetchSortStatus(topic) {
const res = await fetch(`${BASE}/bausteine/sort/status?topic=${encodeURIComponent(topic)}`)
return res.json()
}
export async function fetchSuggestions(topic) {
const res = await fetch(`${BASE}/bausteine/suggestions?topic=${encodeURIComponent(topic)}`)
return res.json()

View File

@@ -5,6 +5,8 @@ import {
createBaustein,
deleteBaustein,
reworkBaustein,
sortBausteine,
fetchSortStatus,
fetchSuggestions,
generateSuggestions,
fetchSuggestionsStatus,
@@ -21,6 +23,9 @@ const suggestions = ref([])
const suggestionsLoading = ref(false)
const newTitle = ref('')
const newInfo = ref('')
const sortInfo = ref('')
const sortingActive = ref(false)
let sortPollTimer = null
const reworkInputs = ref({})
const reworkingIds = ref(new Set())
const reworkingSnapshots = new Map()
@@ -95,6 +100,26 @@ async function handleRegenerate() {
startPolling()
}
async function handleSort() {
sortingActive.value = true
const info = sortInfo.value.trim()
await sortBausteine(props.topic, info)
startSortPolling()
}
function startSortPolling() {
if (sortPollTimer) return
sortPollTimer = setInterval(async () => {
const status = await fetchSortStatus(props.topic)
if (!status.sorting) {
sortingActive.value = false
clearInterval(sortPollTimer)
sortPollTimer = null
bausteine.value = await fetchBausteine(props.topic)
}
}, 3000)
}
async function handleRework(b) {
const instructions = (reworkInputs.value[b.id] || '').trim()
if (!instructions) return
@@ -147,6 +172,10 @@ function stopPolling() {
clearInterval(bausteinPollTimer)
bausteinPollTimer = null
}
if (sortPollTimer) {
clearInterval(sortPollTimer)
sortPollTimer = null
}
}
async function init() {
@@ -177,12 +206,22 @@ onUnmounted(stopPolling)
placeholder="Thema…"
@keyup.enter="handleAdd"
/>
<textarea
<input
v-model="newInfo"
placeholder="Zusätzliche Infos (optional)…"
rows="4"
></textarea>
@keyup.enter="handleAdd"
/>
<button class="new-btn" @click="handleAdd" :disabled="!newTitle.trim()">Generieren</button>
<h3 class="new-card-section">Ordnen</h3>
<input
v-model="sortInfo"
placeholder="Zusätzliche Infos (optional)…"
@keyup.enter="handleSort"
/>
<button class="new-btn" @click="handleSort" :disabled="sortingActive || !bausteine.length">
{{ sortingActive ? 'Ordne…' : 'Ordnen' }}
</button>
</div>
<div v-for="b in bausteine" :key="b.id" class="card">
@@ -297,8 +336,13 @@ onUnmounted(stopPolling)
margin: 0;
}
.new-card input,
.new-card textarea {
.new-card-section {
margin-top: 0.75rem;
padding-top: 0.75rem;
border-top: 1px solid #e2e5e9;
}
.new-card input {
width: 100%;
padding: 8px 10px;
border: 1px solid #d8dde3;
@@ -306,11 +350,9 @@ onUnmounted(stopPolling)
font-size: 0.85rem;
font-family: inherit;
outline: none;
resize: vertical;
}
.new-card input:focus,
.new-card textarea:focus {
.new-card input:focus {
border-color: #6366f1;
}
@@ -323,7 +365,6 @@ onUnmounted(stopPolling)
font-size: 0.85rem;
font-weight: 600;
cursor: pointer;
margin-top: auto;
}
.new-btn:disabled {