feat(ui): show position, time, duration and responsible on agenda items
This commit is contained in:
parent
41426ff25b
commit
a33f2d3f4f
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import SlideUploader from '@/Components/SlideUploader.vue'
|
import SlideUploader from '@/Components/SlideUploader.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
@ -12,6 +12,12 @@ const emit = defineEmits(['slides-updated'])
|
||||||
|
|
||||||
const showUploader = ref(false)
|
const showUploader = ref(false)
|
||||||
|
|
||||||
|
const responsibleNames = computed(() => {
|
||||||
|
const r = props.agendaItem.responsible
|
||||||
|
if (!r || !Array.isArray(r) || r.length === 0) return ''
|
||||||
|
return r.map((p) => p.name || p.title || p.personName || '').filter(Boolean).join(', ')
|
||||||
|
})
|
||||||
|
|
||||||
function onUploaded() {
|
function onUploaded() {
|
||||||
showUploader.value = false
|
showUploader.value = false
|
||||||
emit('slides-updated')
|
emit('slides-updated')
|
||||||
|
|
@ -33,12 +39,25 @@ function onUploaded() {
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<!-- Position + Titel -->
|
<!-- Position + Titel -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="text-xs text-gray-400 tabular-nums">{{ agendaItem.sort_order }}.</span>
|
<span class="text-xs text-gray-400 tabular-nums">{{ agendaItem.position || agendaItem.sort_order }}.</span>
|
||||||
<h4 class="font-medium text-gray-900" data-testid="agenda-item-title">
|
<h4 class="font-medium text-gray-900" data-testid="agenda-item-title">
|
||||||
{{ agendaItem.title }}
|
{{ agendaItem.title }}
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Meta: Zeit, Dauer, Verantwortlich -->
|
||||||
|
<div class="mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-gray-400">
|
||||||
|
<span v-if="agendaItem.start">
|
||||||
|
🕐 {{ agendaItem.start }}
|
||||||
|
</span>
|
||||||
|
<span v-if="agendaItem.duration">
|
||||||
|
⏱ {{ agendaItem.duration }}
|
||||||
|
</span>
|
||||||
|
<span v-if="responsibleNames">
|
||||||
|
👤 {{ responsibleNames }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Notiz (optional) -->
|
<!-- Notiz (optional) -->
|
||||||
<p v-if="agendaItem.note" class="mt-1 text-xs text-gray-500">
|
<p v-if="agendaItem.note" class="mt-1 text-xs text-gray-500">
|
||||||
{{ agendaItem.note }}
|
{{ agendaItem.note }}
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,12 @@ const arrangementPills = computed(() => {
|
||||||
return [...groups].sort((a, b) => a.order - b.order)
|
return [...groups].sort((a, b) => a.order - b.order)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const responsibleNames = computed(() => {
|
||||||
|
const r = props.agendaItem.responsible
|
||||||
|
if (!r || !Array.isArray(r) || r.length === 0) return ''
|
||||||
|
return r.map((p) => p.name || p.title || p.personName || '').filter(Boolean).join(', ')
|
||||||
|
})
|
||||||
|
|
||||||
function openDropdown() {
|
function openDropdown() {
|
||||||
dropdownOpen.value = true
|
dropdownOpen.value = true
|
||||||
}
|
}
|
||||||
|
|
@ -165,11 +171,22 @@ function formatDateTime(value) {
|
||||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="text-xs text-gray-400 tabular-nums">{{ agendaItem.sort_order }}.</span>
|
<span class="text-xs text-gray-400 tabular-nums">{{ agendaItem.position || agendaItem.sort_order }}.</span>
|
||||||
<h4 class="text-lg font-semibold text-gray-900" data-testid="song-agenda-title">
|
<h4 class="text-lg font-semibold text-gray-900" data-testid="song-agenda-title">
|
||||||
{{ serviceSong?.cts_song_name || agendaItem.title || '-' }}
|
{{ serviceSong?.cts_song_name || agendaItem.title || '-' }}
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-gray-400">
|
||||||
|
<span v-if="agendaItem.start">
|
||||||
|
🕐 {{ agendaItem.start }}
|
||||||
|
</span>
|
||||||
|
<span v-if="agendaItem.duration">
|
||||||
|
⏱ {{ agendaItem.duration }}
|
||||||
|
</span>
|
||||||
|
<span v-if="responsibleNames">
|
||||||
|
👤 {{ responsibleNames }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div class="mt-1.5 flex flex-wrap items-center gap-2 text-xs text-gray-600">
|
<div class="mt-1.5 flex flex-wrap items-center gap-2 text-xs text-gray-600">
|
||||||
<span class="rounded-full bg-gray-100 px-2.5 py-1 font-medium">
|
<span class="rounded-full bg-gray-100 px-2.5 py-1 font-medium">
|
||||||
CCLI: {{ serviceSong?.song?.ccli_id || serviceSong?.cts_ccli_id || '-' }}
|
CCLI: {{ serviceSong?.song?.ccli_id || serviceSong?.cts_ccli_id || '-' }}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue