11import { Codesnippet } from "@/components/CodeSnippet" ;
22import { CollapsibleCard } from "@/components/CollapsibleCard" ;
33import { SheetHeader } from "@/components/sheet/SheetHeader" ;
4- import { flavorQueries } from "@/data/flavors" ;
54import { stackQueries } from "@/data/stacks" ;
65import { extractComponents } from "@/lib/components" ;
76import { snakeCaseToTitleCase } from "@/lib/strings" ;
87import { sanitizeUrl } from "@/lib/url" ;
9- import { StackComponent , StackComponentType } from "@/types/components" ;
8+ import { StackComponent } from "@/types/components" ;
109import { useQuery } from "@tanstack/react-query" ;
1110import {
1211 Avatar ,
@@ -78,8 +77,28 @@ function StackHeadline({ stackId }: Props) {
7877}
7978
8079function ComponentList ( { stackId } : Props ) {
80+ const { setIntegrations } = useIntegrationsContext ( ) ;
8181 const stack = useQuery ( { ...stackQueries . stackDetail ( stackId ) } ) ;
8282
83+ useEffect ( ( ) => {
84+ if ( ! stack . data ) return ;
85+
86+ const components = extractComponents (
87+ stack . data . metadata ?. components as Record < string , StackComponent [ ] > | undefined
88+ ) ;
89+
90+ const integrations = components
91+ . map ( ( component ) => component . body ?. integration )
92+ . filter (
93+ ( integration ) : integration is string =>
94+ ! ! integration && integration !== "built-in" && integration !== "custom"
95+ ) ;
96+
97+ if ( integrations . length >= 1 ) {
98+ setIntegrations ( ( prev ) => Array . from ( new Set ( [ ...prev , ...integrations ] ) ) ) ;
99+ }
100+ } , [ stack . data ] ) ;
101+
83102 if ( stack . isError ) return null ;
84103 if ( stack . isPending )
85104 return (
@@ -110,9 +129,11 @@ function ComponentListItem({ component }: ComponentListItemProps) {
110129 return (
111130 < Box className = "flex items-center justify-between p-5" >
112131 < div className = "flex items-center space-x-3" >
113- < FlavorIcon
114- flavor = { component . body ?. flavor || "" }
115- type = { component . body ?. type || "orchestrator" }
132+ < img
133+ width = { 32 }
134+ height = { 32 }
135+ alt = { `${ component . body ?. flavor } logo` }
136+ src = { sanitizeUrl ( component . body ?. logo_url || "" ) }
116137 />
117138 < div >
118139 < ComponentFallbackDialog
@@ -134,41 +155,6 @@ function ComponentListItem({ component }: ComponentListItemProps) {
134155 ) ;
135156}
136157
137- type FlavorIconProps = {
138- flavor : string ;
139- type : StackComponentType ;
140- } ;
141-
142- function FlavorIcon ( { flavor, type } : FlavorIconProps ) {
143- const { setIntegrations } = useIntegrationsContext ( ) ;
144- const flavorQuery = useQuery ( { ...flavorQueries . flavorList ( { name : flavor , type } ) } ) ;
145-
146- useEffect ( ( ) => {
147- if (
148- flavorQuery . data ?. items ?. length &&
149- flavorQuery . data . items [ 0 ] . body ?. integration &&
150- flavorQuery . data . items [ 0 ] . body . integration !== "built-in"
151- ) {
152- setIntegrations ( ( prev ) => {
153- const newIntegration = flavorQuery . data . items [ 0 ] . body ?. integration || "" ;
154- return Array . from ( new Set ( [ ...prev , newIntegration ] ) ) . filter ( Boolean ) ;
155- } ) ;
156- }
157- } , [ setIntegrations , flavorQuery . data ] ) ;
158-
159- if ( flavorQuery . isError ) return null ;
160- if ( flavorQuery . isPending ) return < Skeleton className = "h-6 w-6" /> ;
161-
162- return (
163- < img
164- width = { 32 }
165- height = { 32 }
166- alt = { `${ flavor } logo` }
167- src = { sanitizeUrl ( flavorQuery . data . items [ 0 ] . body ?. logo_url ?? "" ) }
168- />
169- ) ;
170- }
171-
172158type StackSetCommandProps = {
173159 name : string ;
174160} ;
0 commit comments