@@ -32,7 +32,12 @@ import {
3232} from '../serialization' ;
3333import { TagService } from './tag.service' ;
3434import { UserService } from './user.service' ;
35- import { addMissionFilters , addProjectFilters , addSort } from './utilities' ;
35+ import {
36+ addFileStats ,
37+ addMissionFilters ,
38+ addProjectFilters ,
39+ addSort ,
40+ } from './utilities' ;
3641
3742import { SortOrder } from '@common/api/types/pagination' ;
3843
@@ -162,36 +167,104 @@ export class MissionService {
162167 take : number ,
163168 userUuid : string ,
164169 ) : Promise < MissionsDto > {
165- let query = this . missionRepository
170+ let idQuery = this . missionRepository
166171 . createQueryBuilder ( 'mission' )
167- . leftJoinAndSelect ( 'mission.project' , 'project' )
168- . leftJoinAndSelect ( 'mission.creator' , 'creator' )
169- . leftJoinAndSelect ( 'mission.tags' , 'tag' )
170- . leftJoinAndSelect ( 'tag.tagType' , 'tagType' ) ;
172+ . select ( 'mission.uuid' )
173+ . leftJoin ( 'mission.project' , 'project' )
174+ . leftJoin ( 'mission.creator' , 'creator' )
175+ . leftJoin ( 'mission.tags' , 'tag' )
176+ . leftJoin ( 'tag.tagType' , 'tagType' ) ;
171177
172- query = addAccessConstraintsToMissionQuery ( query , userUuid ) ;
178+ idQuery = addAccessConstraintsToMissionQuery ( idQuery , userUuid ) ;
173179
174- query = addProjectFilters (
175- query ,
180+ idQuery = addProjectFilters (
181+ idQuery ,
176182 this . projectRepository ,
177183 projectUuids ,
178184 projectPatterns ,
179185 ) ;
180186
181- query = addMissionFilters (
182- query ,
187+ idQuery = addMissionFilters (
188+ idQuery ,
183189 this . missionRepository ,
184190 missionUuids ,
185191 missionPatterns ,
186192 missionMetadata ,
187193 ) ;
188194
189195 if ( sortBy !== undefined ) {
190- query = addSort ( query , FIND_MANY_SORT_KEYS , sortBy , sortOrder ) ;
196+ idQuery = addSort ( idQuery , FIND_MANY_SORT_KEYS , sortBy , sortOrder ) ;
191197 }
192198
193- query . take ( take ) . skip ( skip ) ;
194- const [ missions , count ] = await query . getManyAndCount ( ) ;
199+ // Get distinct mission UUIDs
200+ idQuery . groupBy ( 'mission.uuid' ) ;
201+
202+ // Get count before pagination
203+ const count = await idQuery . getCount ( ) ;
204+ idQuery . take ( take ) . skip ( skip ) ;
205+
206+ const missionIds = await idQuery . getRawMany ( ) ;
207+
208+ if ( missionIds . length === 0 ) {
209+ return {
210+ data : [ ] ,
211+ count,
212+ skip,
213+ take,
214+ } ;
215+ }
216+
217+ let dataQuery = this . missionRepository
218+ . createQueryBuilder ( 'mission' )
219+ . leftJoinAndSelect ( 'mission.project' , 'project' )
220+ . leftJoinAndSelect ( 'mission.creator' , 'creator' )
221+ . leftJoinAndSelect ( 'mission.tags' , 'tag' )
222+ . leftJoinAndSelect ( 'tag.tagType' , 'tagType' )
223+ . where ( 'mission.uuid IN (:...missionIds)' , {
224+ missionIds : missionIds . map ( ( m ) => m . mission_uuid ) ,
225+ } ) ;
226+
227+ if ( sortBy !== undefined ) {
228+ dataQuery = addSort (
229+ dataQuery ,
230+ FIND_MANY_SORT_KEYS ,
231+ sortBy ,
232+ sortOrder ,
233+ ) ;
234+ }
235+
236+ dataQuery = addFileStats ( dataQuery ) ;
237+
238+ const result = await dataQuery . getRawAndEntities ( ) ;
239+ const missions = result . entities ;
240+ const rawResults = result . raw ;
241+
242+ // Create a map for quick lookup of file stats by mission UUID
243+ const statsMap = new Map <
244+ string ,
245+ { fileCount : number ; fileSize : number }
246+ > ( ) ;
247+ for ( const raw of rawResults ) {
248+ const missionUuid = raw . mission_uuid ;
249+ if ( ! statsMap . has ( missionUuid ) ) {
250+ statsMap . set ( missionUuid , {
251+ fileCount : Number . parseInt ( raw . fileCount ) || 0 ,
252+ fileSize : Number . parseInt ( raw . fileSize ) || 0 ,
253+ } ) ;
254+ }
255+ }
256+
257+ // Assign file stats to missions
258+ for ( const mission of missions ) {
259+ const stats = statsMap . get ( mission . uuid ) ;
260+ if ( stats ) {
261+ mission . fileCount = stats . fileCount ;
262+ mission . size = stats . fileSize ;
263+ } else {
264+ mission . fileCount = 0 ;
265+ mission . size = 0 ;
266+ }
267+ }
195268
196269 return {
197270 data : missions . map ( ( element ) => missionEntityToFlatDto ( element ) ) ,
0 commit comments