init
This commit is contained in:
72
frontend/src/components/EinheitDetail.vue
Normal file
72
frontend/src/components/EinheitDetail.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user