11import { Injectable , NotFoundException } from '@nestjs/common' ;
2- import { Observable , catchError , firstValueFrom , from , map , of , switchMap , throwError } from 'rxjs' ;
2+ import { Observable , catchError , firstValueFrom , forkJoin , from , map , of , switchMap , throwError } from 'rxjs' ;
33
44import { Articles } from '@o2s/framework/modules' ;
55
@@ -22,7 +22,13 @@ import { showUser } from '@/generated/zendesk';
2222import type { UserObject } from '@/generated/zendesk' ;
2323import { client as ticketingClient } from '@/generated/zendesk/client.gen' ;
2424
25- import { mapArticle , mapArticlesWithCategories , mapCategories , mapCategory } from './zendesk-article.mapper' ;
25+ import {
26+ mapArticle ,
27+ mapArticlesWithCategories ,
28+ mapCategories ,
29+ mapCategory ,
30+ mapSearchArticles ,
31+ } from './zendesk-article.mapper' ;
2632
2733type ZendeskArticle = ArticleObject ;
2834type ZendeskCategory = CategoryObject ;
@@ -170,60 +176,50 @@ export class ZendeskArticleService extends Articles.Service {
170176 switchMap ( ( response ) => {
171177 const articles = response . articles || [ ] ;
172178
173- // Fetch attachments and authors for all articles in parallel
174- const attachmentsPromises = articles . map ( ( article ) =>
175- firstValueFrom (
176- this . fetchArticleAttachments ( article . id ! , zendeskLocale ) . pipe ( catchError ( ( ) => of ( [ ] ) ) ) ,
177- ) ,
179+ if ( articles . length === 0 ) {
180+ return of ( mapArticlesWithCategories ( articles , 0 , options . locale , [ ] , [ ] , [ ] ) ) ;
181+ }
182+
183+ // Fetch attachments, authors, and categories in parallel using forkJoin
184+ const attachments$ = articles . map ( ( article ) =>
185+ this . fetchArticleAttachments ( article . id ! , zendeskLocale ) . pipe ( catchError ( ( ) => of ( [ ] ) ) ) ,
178186 ) ;
179187
180- const authorsPromises = articles . map ( ( article ) =>
188+ const authors$ = articles . map ( ( article ) =>
181189 article . author_id
182- ? firstValueFrom (
183- this . fetchUser ( article . author_id ) . pipe ( catchError ( ( ) => of ( undefined ) ) ) ,
184- )
185- : Promise . resolve ( undefined ) ,
190+ ? this . fetchUser ( article . author_id ) . pipe ( catchError ( ( ) => of ( undefined ) ) )
191+ : of ( undefined ) ,
186192 ) ;
187193
188194 // If category filter is provided, use that category for all articles
189195 // Otherwise, fetch category for each article via section_id -> category_id
190- const categoriesPromises = category
191- ? articles . map ( ( ) => Promise . resolve ( category ) )
196+ const categories$ = category
197+ ? articles . map ( ( ) => of ( category ) )
192198 : articles . map ( ( article ) =>
193199 article . section_id
194- ? firstValueFrom (
195- this . fetchSection ( article . section_id , zendeskLocale ) . pipe (
196- switchMap ( ( section ) => {
197- if ( ! section ?. category_id ) {
198- return of ( undefined ) ;
199- }
200- return this . fetchCategory ( section . category_id , zendeskLocale ) ;
201- } ) ,
202- catchError ( ( ) => of ( undefined ) ) ,
203- ) ,
200+ ? this . fetchSection ( article . section_id , zendeskLocale ) . pipe (
201+ switchMap ( ( section ) => {
202+ if ( ! section ?. category_id ) {
203+ return of ( undefined ) ;
204+ }
205+ return this . fetchCategory ( section . category_id , zendeskLocale ) ;
206+ } ) ,
207+ catchError ( ( ) => of ( undefined ) ) ,
204208 )
205- : Promise . resolve ( undefined ) ,
209+ : of ( undefined ) ,
206210 ) ;
207211
208- return from (
209- Promise . all ( [
210- Promise . all ( attachmentsPromises ) ,
211- Promise . all ( authorsPromises ) ,
212- Promise . all ( categoriesPromises ) ,
213- ] ) ,
214- ) . pipe (
215- map ( ( [ attachmentsArray , authorsArray , categoriesArray ] ) => {
216- // Zendesk doesn't provide total count in the response, so we use articles.length
217- // In a real scenario, you might need to make additional requests to get the total
218- return mapArticlesWithCategories (
212+ return forkJoin ( [ forkJoin ( attachments$ ) , forkJoin ( authors$ ) , forkJoin ( categories$ ) ] ) . pipe (
213+ map ( ( [ attachmentsArray , authorsArray , categoriesArray ] ) =>
214+ mapArticlesWithCategories (
219215 articles ,
220216 articles . length ,
221217 options . locale ,
222218 attachmentsArray ,
223219 authorsArray ,
224220 categoriesArray ,
225- ) ;
226- } ) ,
221+ ) ,
222+ ) ,
227223 ) ;
228224 } ) ,
229225 ) ;
@@ -378,56 +374,29 @@ export class ZendeskArticleService extends Articles.Service {
378374 switchMap ( ( response ) => {
379375 const articles = response . data ?. results || [ ] ;
380376
381- // Fetch attachments, authors, and categories for all articles in parallel
382- const attachmentsPromises = articles . map ( ( article ) =>
383- firstValueFrom (
384- this . fetchArticleAttachments ( article . id ! , zendeskLocale ) . pipe ( catchError ( ( ) => of ( [ ] ) ) ) ,
385- ) ,
386- ) ;
387-
388- const authorsPromises = articles . map ( ( article ) =>
389- article . author_id
390- ? firstValueFrom (
391- this . fetchUser ( article . author_id ) . pipe ( catchError ( ( ) => of ( undefined ) ) ) ,
392- )
393- : Promise . resolve ( undefined ) ,
394- ) ;
377+ if ( articles . length === 0 ) {
378+ return of ( mapSearchArticles ( articles , 0 , options . locale , [ ] ) ) ;
379+ }
395380
396- // Fetch category for each article via section_id -> category_id
397- // This ensures full slugs even when no category filter is provided
398- const categoriesPromises = articles . map ( ( article ) =>
381+ // Fetch only categories for search results (no attachments/authors needed)
382+ const categories$ = articles . map ( ( article ) =>
399383 article . section_id
400- ? firstValueFrom (
401- this . fetchSection ( article . section_id , zendeskLocale ) . pipe (
402- switchMap ( ( section ) => {
403- if ( ! section ?. category_id ) {
404- return of ( undefined ) ;
405- }
406- return this . fetchCategory ( section . category_id , zendeskLocale ) ;
407- } ) ,
408- catchError ( ( ) => of ( undefined ) ) ,
409- ) ,
384+ ? this . fetchSection ( article . section_id , zendeskLocale ) . pipe (
385+ switchMap ( ( section ) => {
386+ if ( ! section ?. category_id ) {
387+ return of ( undefined ) ;
388+ }
389+ return this . fetchCategory ( section . category_id , zendeskLocale ) ;
390+ } ) ,
391+ catchError ( ( ) => of ( undefined ) ) ,
410392 )
411- : Promise . resolve ( undefined ) ,
393+ : of ( undefined ) ,
412394 ) ;
413395
414- return from (
415- Promise . all ( [
416- Promise . all ( attachmentsPromises ) ,
417- Promise . all ( authorsPromises ) ,
418- Promise . all ( categoriesPromises ) ,
419- ] ) ,
420- ) . pipe (
421- map ( ( [ attachmentsArray , authorsArray , categoriesArray ] ) => {
422- return mapArticlesWithCategories (
423- articles ,
424- articles . length ,
425- options . locale ,
426- attachmentsArray ,
427- authorsArray ,
428- categoriesArray ,
429- ) ;
430- } ) ,
396+ return forkJoin ( categories$ ) . pipe (
397+ map ( ( categoriesArray ) =>
398+ mapSearchArticles ( articles , articles . length , options . locale , categoriesArray ) ,
399+ ) ,
431400 ) ;
432401 } ) ,
433402 catchError ( ( error ) => {
0 commit comments