45 lines
1.2 KiB
Vue
45 lines
1.2 KiB
Vue
<script setup>
|
|
import { onMounted, ref } from 'vue'
|
|
import { fetchProjekte } from '../api.js'
|
|
import { usePolling } from '../composables/usePolling.js'
|
|
import ProjektKarte from './ProjektKarte.vue'
|
|
|
|
defineEmits(['oeffne', 'geaendert'])
|
|
|
|
const projekte = ref([])
|
|
const fehler = ref('')
|
|
|
|
async function laden() {
|
|
try {
|
|
projekte.value = await fetchProjekte()
|
|
fehler.value = ''
|
|
} catch (e) {
|
|
fehler.value = e.message
|
|
}
|
|
}
|
|
|
|
const poll = usePolling(laden, () => projekte.value.some((p) => p.scan_laeuft), 3000)
|
|
onMounted(async () => {
|
|
await laden()
|
|
poll.start()
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<p v-if="fehler" class="fehler">{{ fehler }}</p>
|
|
<p v-else-if="!projekte.length" class="leer">
|
|
Keine Projekte — Pfade in <code>projekte.txt</code> eintragen (eine Zeile = ein Repo).
|
|
</p>
|
|
<div class="liste">
|
|
<ProjektKarte v-for="p in projekte" :key="p.name" :projekt="p"
|
|
@oeffne="$emit('oeffne', p.name)"
|
|
@aktualisiert="laden(); poll.start(); $emit('geaendert')" />
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.liste { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 1rem; }
|
|
.fehler { color: var(--rot); }
|
|
.leer { color: var(--dezent); }
|
|
</style>
|