@@ -105,7 +105,10 @@ const integrationCards = ref<TypeCard[]>([]);
105105const loadingCards = ref (false );
106106const cardLoadError = ref (false );
107107const selectedCardCache = ref <TypeCard | null >(null );
108+ const totalIntegrationCards = ref <number | null >(null );
109+ const hasLoadedFirstPage = ref (false );
108110let wizardActionsObserver: IntersectionObserver | null = null ;
111+ let activeFetchRequestId = 0 ;
109112
110113const getCardFilter = (category : IntegrationCategory ) => {
111114 return t (` integrations.create.wizard.step1.filters.${category } ` );
@@ -298,8 +301,12 @@ const buildCardFromNode = (node: PublicIntegrationTypeNode): TypeCard => ({
298301});
299302
300303const fetchIntegrationCards = async () => {
304+ const requestId = ++ activeFetchRequestId ;
301305 loadingCards .value = true ;
302306 cardLoadError .value = false ;
307+ integrationCards .value = [];
308+ totalIntegrationCards .value = null ;
309+ hasLoadedFirstPage .value = false ;
303310
304311 try {
305312 const filter: Record <string , any > = {
@@ -332,21 +339,34 @@ const fetchIntegrationCards = async () => {
332339 fetchPolicy: ' network-only' ,
333340 });
334341
342+ if (requestId !== activeFetchRequestId ) {
343+ return ;
344+ }
345+
335346 const connection = data ?.publicIntegrationTypes ;
336347 const currentEdges = connection ?.edges || [];
337348
338349 edges .push (... currentEdges );
350+ integrationCards .value = edges .map ((edge ) => buildCardFromNode (edge .node ));
351+ totalIntegrationCards .value = connection ?.totalCount ?? edges .length ;
352+ hasLoadedFirstPage .value = true ;
339353 hasNextPage = Boolean (connection ?.pageInfo ?.hasNextPage );
340354 after = connection ?.pageInfo ?.endCursor || null ;
341355 }
342-
343- integrationCards .value = edges .map ((edge ) => buildCardFromNode (edge .node ));
344356 } catch (error ) {
357+ if (requestId !== activeFetchRequestId ) {
358+ return ;
359+ }
360+
345361 integrationCards .value = [];
362+ totalIntegrationCards .value = null ;
363+ hasLoadedFirstPage .value = true ;
346364 cardLoadError .value = true ;
347365 console .error (' Failed to load public integration types' , error );
348366 } finally {
349- loadingCards .value = false ;
367+ if (requestId === activeFetchRequestId ) {
368+ loadingCards .value = false ;
369+ }
350370 }
351371};
352372
@@ -364,6 +384,8 @@ const scheduleCardFetch = () => {
364384
365385const visibleCards = computed (() => integrationCards .value );
366386const filteredCount = computed (() => visibleCards .value .length );
387+ const showInlineLoadingState = computed (() => loadingCards .value && hasLoadedFirstPage .value && visibleCards .value .length > 0 );
388+ const loadingProgressTotal = computed (() => totalIntegrationCards .value ?? filteredCount .value );
367389const selectedCard = computed (() => {
368390 const currentCard = integrationCards .value .find ((card ) => card .value === selectedType .value ) || null ;
369391 if (currentCard ) {
@@ -508,6 +530,7 @@ onBeforeUnmount(() => {
508530 <SearchInput
509531 v-model =" searchTerm"
510532 :placeholder =" t('integrations.create.wizard.step1.searchPlaceholder')"
533+ :loading =" loadingCards"
511534 />
512535
513536 <div class =" flex flex-col gap-3 rounded-2xl border border-slate-200 bg-white/90 px-4 py-3 shadow-sm sm:flex-row sm:items-center" >
@@ -593,6 +616,21 @@ onBeforeUnmount(() => {
593616 </div >
594617
595618 <div v-else class =" space-y-10" >
619+ <div
620+ v-if =" showInlineLoadingState"
621+ class =" flex items-center gap-3 rounded-2xl border border-slate-200 bg-white/90 px-4 py-3 text-sm text-slate-600 shadow-sm"
622+ >
623+ <Icon name =" circle-notch" size =" sm" spin class =" text-primary" />
624+ <div class =" min-w-0" >
625+ <p class =" font-medium text-slate-800" >
626+ {{ t('integrations.create.wizard.step1.loadingMore.title') }}
627+ </p >
628+ <p class =" text-xs text-slate-500" >
629+ {{ t('integrations.create.wizard.step1.loadingMore.description', { loaded: filteredCount, total: loadingProgressTotal }) }}
630+ </p >
631+ </div >
632+ </div >
633+
596634 <section
597635 v-for =" section in visibleSections"
598636 :key =" section.key"
0 commit comments