Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/components/tags/TagsAdmin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
<option value="person">Personen</option>
<option value="song">Lieder</option>
<option value="group">Gruppen</option>
<option value="appointment">Termine</option>
</select>
</div>
</template>
Expand Down Expand Up @@ -232,6 +233,7 @@
<option value="person">Personen</option>
<option value="song">Lieder</option>
<option value="group">Gruppen</option>
<option value="appointment">Termine</option>
</select>
<input
v-else
Expand Down Expand Up @@ -573,6 +575,7 @@ const getDomainDisplayName = (domain: string) => {
person: 'Personen',
song: 'Lieder',
group: 'Gruppen',
appointment: 'Termine',
}
return domainNames[domain as keyof typeof domainNames] || domain
}
Expand Down
9 changes: 8 additions & 1 deletion src/components/tags/TagsCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const { data: tags, isLoading, error, refetch, isFetching, dataUpdatedAt } = use

// Compute stats using the helper function
const stats = computed(() => {
if (!tags.value) return { total: 0, person: 0, song: 0, group: 0 }
if (!tags.value) return { total: 0, person: 0, song: 0, group: 0, appointment: 0 }
return useTagsStats(tags.value)
})

Expand Down Expand Up @@ -74,6 +74,13 @@ const statusStats = computed(() => [
icon: '👥',
type: 'warning' as const,
},
{
key: 'appointment',
value: stats.value.appointment,
label: 'Termine',
icon: '📅',
type: 'primary' as const,
},
])

const formattedLastUpdate = computed(() => {
Expand Down
9 changes: 8 additions & 1 deletion src/components/tags/useTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export function useTags() {
() => tags.value.filter((tag) => tag.domainType === 'group').length
)

const appointmentTagsCount = computed(
() => tags.value.filter((tag) => tag.domainType === 'appointment').length
)

// Note: Domain filtering is now handled at API level in fetchTags
// No need for client-side domain filtering since we only load the selected domain

Expand All @@ -35,7 +39,9 @@ export function useTags() {
error.value = null

try {
const domains = selectedDomain.value ? [selectedDomain.value] : ['person', 'song', 'group']
const domains = selectedDomain.value
? [selectedDomain.value]
: ['person', 'song', 'group', 'appointment']

const tagPromises = domains.map(async (domain) => {
try {
Expand Down Expand Up @@ -164,6 +170,7 @@ export function useTags() {
personTagsCount,
songTagsCount,
groupTagsCount,
appointmentTagsCount,

fetchTags,
createTag,
Expand Down
15 changes: 13 additions & 2 deletions src/composables/useTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface Tag {
name: string
description?: string
color?: string
domainType: 'person' | 'song' | 'group'
domainType: 'person' | 'song' | 'group' | 'appointment'
}

type TagsApiResponse = Tag[]
Expand All @@ -16,10 +16,11 @@ async function fetchTags(): Promise<Tag[]> {
const startTime = performance.now()
console.log('🏷️ Fetching tags...')
// Fetch tags from different domains using modern API endpoints
const [personTags, songTags, groupTags] = await Promise.allSettled([
const [personTags, songTags, groupTags, appointmentTags] = await Promise.allSettled([
churchtoolsClient.get<TagsApiResponse>('/tags/person').catch(() => []),
churchtoolsClient.get<TagsApiResponse>('/tags/song').catch(() => []),
churchtoolsClient.get<TagsApiResponse>('/tags/group').catch(() => []),
churchtoolsClient.get<TagsApiResponse>('/tags/appointment').catch(() => []),
])

const allTags: Tag[] = []
Expand All @@ -42,6 +43,14 @@ async function fetchTags(): Promise<Tag[]> {
allTags.push(...groupTagsData.map((tag: any) => ({ ...tag, domainType: 'group' as const })))
}

// Process appointment tags
if (appointmentTags.status === 'fulfilled' && appointmentTags.value) {
const appointmentTagsData = Array.isArray(appointmentTags.value) ? appointmentTags.value : []
allTags.push(
...appointmentTagsData.map((tag: any) => ({ ...tag, domainType: 'appointment' as const }))
)
}

const endTime = performance.now()
console.log(`🏷️ Tags fetched: ${allTags.length} tags in ${Math.round(endTime - startTime)}ms`)
return allTags
Expand All @@ -62,11 +71,13 @@ export function useTagsStats(tags: Tag[]) {
const personTagsCount = tags.filter((tag) => tag.domainType === 'person').length
const songTagsCount = tags.filter((tag) => tag.domainType === 'song').length
const groupTagsCount = tags.filter((tag) => tag.domainType === 'group').length
const appointmentTagsCount = tags.filter((tag) => tag.domainType === 'appointment').length

return {
total: tags.length,
person: personTagsCount,
song: songTagsCount,
group: groupTagsCount,
appointment: appointmentTagsCount,
}
}