From 96da8814444178ce96fb0f2044648711f6e85a61 Mon Sep 17 00:00:00 2001 From: Bernhard Weichel Date: Sat, 27 Sep 2025 12:49:26 +0000 Subject: [PATCH] fix: display group type names instead of IDs in automatic groups - Fetch group types from /group/grouptypes API to create ID-to-name mapping - Access groupTypeId from correct field path (group.information.groupTypeId) - Update interface to include both groupTypeId (number) and groupTypeName (string) - Update admin table to display groupTypeName instead of groupTypeId - Add robust error handling for group types API calls - Include domainAttributes in groups API call for complete data Resolves issue where automatic groups showed 'Unbekannter Typ' instead of actual group type names like 'Hauskreis', 'Mitarbeiterteam', etc. Co-authored-by: Ona --- .../automatic-groups/AutomaticGroupsAdmin.vue | 4 +- src/composables/useAutomaticGroups.ts | 77 +++++++++++++++---- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/components/automatic-groups/AutomaticGroupsAdmin.vue b/src/components/automatic-groups/AutomaticGroupsAdmin.vue index ce9543b..43a384e 100644 --- a/src/components/automatic-groups/AutomaticGroupsAdmin.vue +++ b/src/components/automatic-groups/AutomaticGroupsAdmin.vue @@ -10,7 +10,7 @@ description="Überwachung und Verwaltung aller automatischen Gruppen" searchable search-placeholder="Gruppen durchsuchen..." - :search-fields="['name', 'groupTypeId']" + :search-fields="['name', 'groupTypeName']" default-sort-field="id" loading-text="Lade automatische Gruppen..." empty-text="Keine automatischen Gruppen gefunden." @@ -83,7 +83,7 @@ const adminTableRef = ref() // Table configuration const tableColumns: TableColumn[] = [ { key: 'id', label: 'Gruppen-ID', sortable: true, resizable: true, width: 100 }, - { key: 'groupTypeId', label: 'Gruppentyp', sortable: true, resizable: true, width: 120 }, + { key: 'groupTypeName', label: 'Gruppentyp', sortable: true, resizable: true, width: 120 }, { key: 'name', label: 'Name', diff --git a/src/composables/useAutomaticGroups.ts b/src/composables/useAutomaticGroups.ts index 0a74461..bb9a572 100644 --- a/src/composables/useAutomaticGroups.ts +++ b/src/composables/useAutomaticGroups.ts @@ -4,7 +4,8 @@ import { churchtoolsClient } from '@churchtools/churchtools-client' export interface AutomaticGroup { id: number name: string - groupTypeId?: string + groupTypeId: number + groupTypeName: string dynamicGroupStatus: string lastExecution: string | null executionStatus: 'success' | 'error' | 'running' | 'pending' | 'unknown' @@ -29,6 +30,36 @@ function determineExecutionStatus(group: any): AutomaticGroup['executionStatus'] } async function fetchAutomaticGroups(): Promise { + // First, fetch all group types to create a mapping + let groupTypeMap = new Map() + + try { + const groupTypesResponse = await churchtoolsClient.get('/group/grouptypes') + + // Handle different response structures + let groupTypes: any[] = [] + if ( + groupTypesResponse && + (groupTypesResponse as any).data && + Array.isArray((groupTypesResponse as any).data) + ) { + groupTypes = (groupTypesResponse as any).data + } else if (Array.isArray(groupTypesResponse)) { + groupTypes = groupTypesResponse + } else { + console.warn('Unexpected group types response structure:', groupTypesResponse) + } + + groupTypes.forEach((groupType: any) => { + if (groupType.id && groupType.name) { + groupTypeMap.set(groupType.id, groupType.name) + } + }) + } catch (error) { + console.warn('Failed to fetch group types:', error) + // Continue without group type mapping + } + let allGroups: any[] = [] let page = 1 const limit = 100 @@ -37,16 +68,16 @@ async function fetchAutomaticGroups(): Promise { // Fetch all groups with proper pagination while (hasMore) { const response = await churchtoolsClient.get( - `/groups?include=settings&limit=${limit}&page=${page}` + `/groups?include=settings,domainAttributes&limit=${limit}&page=${page}` ) let pageGroups: any[] = [] - if (Array.isArray(response)) { - pageGroups = response - } else if (response && (response as any).data && Array.isArray((response as any).data)) { + if (response && (response as any).data && Array.isArray((response as any).data)) { pageGroups = (response as any).data - } else if (response && Array.isArray((response as any).groups)) { - pageGroups = (response as any).groups + } else if (Array.isArray(response)) { + pageGroups = response + } else { + console.warn('Unexpected groups response structure:', response) } if (pageGroups.length === 0) { @@ -70,16 +101,28 @@ async function fetchAutomaticGroups(): Promise { group.settings.dynamicGroupStatus !== 'none' && group.settings.dynamicGroupStatus !== null ) - .map((group) => ({ - id: group.id, - name: group.name || `Gruppe ${group.id}`, - groupTypeId: group.groupTypeId || group.groupType?.name || 'N/A', - dynamicGroupStatus: group.settings?.dynamicGroupStatus || 'none', - lastExecution: group.settings?.dynamicGroupUpdateFinished || null, - executionStatus: determineExecutionStatus(group), - dynamicGroupUpdateStarted: group.settings?.dynamicGroupUpdateStarted || null, - dynamicGroupUpdateFinished: group.settings?.dynamicGroupUpdateFinished || null, - })) + .map((group) => { + // Try different possible locations for groupTypeId + const groupTypeId = + group.information?.groupTypeId || + group.domainAttributes?.groupTypeId || + group.groupTypeId || + 0 + + const groupTypeName = groupTypeMap.get(groupTypeId) || 'Unbekannter Typ' + + return { + id: group.id, + name: group.name || `Gruppe ${group.id}`, + groupTypeId, + groupTypeName, + dynamicGroupStatus: group.settings?.dynamicGroupStatus || 'none', + lastExecution: group.settings?.dynamicGroupUpdateFinished || null, + executionStatus: determineExecutionStatus(group), + dynamicGroupUpdateStarted: group.settings?.dynamicGroupUpdateStarted || null, + dynamicGroupUpdateFinished: group.settings?.dynamicGroupUpdateFinished || null, + } + }) return automaticGroups }