73 lines
2.5 KiB
Vue
73 lines
2.5 KiB
Vue
<script setup>
|
|
import { ref } from 'vue'
|
|
import { fetchEinheit } from '../api.js'
|
|
|
|
const props = defineProps({
|
|
projektName: { type: String, required: true },
|
|
id: { type: String, required: true },
|
|
kurz: { type: String, default: '' },
|
|
})
|
|
|
|
const detail = ref(null)
|
|
const fehler = ref('')
|
|
|
|
async function laden() {
|
|
if (detail.value || fehler.value) return // lazy: einmal beim ersten Aufklappen
|
|
try {
|
|
detail.value = await fetchEinheit(props.projektName, props.id)
|
|
} catch (e) {
|
|
fehler.value = e.message
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<details class="einheit" @toggle="(e) => e.target.open && laden()">
|
|
<summary>
|
|
<code>{{ id }}</code>
|
|
<span v-if="detail?.veraltet" class="badge gelb">veraltet</span>
|
|
</summary>
|
|
<div class="inhalt">
|
|
<p v-if="fehler" class="fehler">{{ fehler }}</p>
|
|
<template v-else-if="detail">
|
|
<p class="besch"><em>{{ detail.beschreibung }}</em></p>
|
|
<dl class="io">
|
|
<dt>Input</dt><dd>{{ detail.input || '—' }}</dd>
|
|
<dt>Output</dt><dd>{{ detail.output || '—' }}</dd>
|
|
</dl>
|
|
<ul v-if="detail.entscheidungen.length" class="entscheidungen">
|
|
<li v-for="(e, i) in detail.entscheidungen" :key="i">{{ e }}</li>
|
|
</ul>
|
|
<p v-if="detail.kanten.length" class="kanten">
|
|
<template v-for="(k, i) in detail.kanten" :key="i">
|
|
<span v-if="i"> · </span>{{ k.typ }} → <code>{{ k.ziel }}</code>
|
|
</template>
|
|
</p>
|
|
<pre v-if="detail.code">{{ detail.code }}</pre>
|
|
<p v-else class="kein-code">Anker nicht im aktuellen Code gefunden.</p>
|
|
</template>
|
|
<p v-else class="laden">lädt…</p>
|
|
</div>
|
|
</details>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.einheit {
|
|
margin: 0.3rem 0 0.5rem 1.1rem; border: 1px solid var(--rand); border-radius: 8px;
|
|
background: var(--bg);
|
|
}
|
|
.einheit > summary { padding: 0.4rem 0.6rem; font-size: 0.82rem; display: flex; gap: 0.5rem; }
|
|
.inhalt { padding: 0.1rem 0.8rem 0.7rem; font-size: 0.9rem; }
|
|
.besch { margin: 0.2rem 0; }
|
|
.io { display: grid; grid-template-columns: max-content 1fr; gap: 0.1rem 0.7rem;
|
|
color: var(--dezent); font-size: 0.85rem; margin: 0.3rem 0; }
|
|
.io dt { font-weight: 600; }
|
|
.io dd { margin: 0; }
|
|
.entscheidungen { margin: 0.3rem 0; padding-left: 1.2rem; }
|
|
.entscheidungen li { margin: 0.15rem 0; }
|
|
.kanten { color: var(--dezent); font-size: 0.82rem; }
|
|
.kein-code { color: var(--gelb); font-size: 0.85rem; }
|
|
.fehler { color: var(--rot); }
|
|
.laden { color: var(--dezent); }
|
|
</style>
|