11import { PackagePlus } from "lucide-react" ;
2- import { type ChangeEvent , useCallback , useMemo } from "react" ;
2+ import { type ChangeEvent } from "react" ;
33
44import { ManageLibrariesDialog } from "@/components/shared/GitHubLibrary/ManageLibrariesDialog" ;
55import { useBetaFlagValue } from "@/components/shared/Settings/useBetaFlags" ;
@@ -39,164 +39,20 @@ const GraphComponents = ({ isOpen }: { isOpen: boolean }) => {
3939 const remoteComponentLibrarySearchEnabled = useBetaFlagValue (
4040 "remote-component-library-search" ,
4141 ) ;
42- const githubComponentLibraryEnabled = useBetaFlagValue (
43- "github-component-library" ,
44- ) ;
45-
46- const { getComponentLibrary, existingComponentLibraries } =
47- useComponentLibrary ( ) ;
4842
4943 const { updateSearchFilter, currentSearchFilter } = useForcedSearchContext ( ) ;
50- const {
51- componentLibrary,
52- usedComponentsFolder,
53- userComponentsFolder,
54- favoritesFolder,
55- isLoading,
56- error,
57- searchResult,
58- } = useComponentLibrary ( ) ;
5944
6045 const handleSearchChange = ( e : ChangeEvent < HTMLInputElement > ) => {
6146 updateSearchFilter ( {
6247 searchTerm : e . target . value ,
6348 } ) ;
6449 } ;
6550
66- const handleFiltersChange = useCallback (
67- ( filters : string [ ] ) => {
68- updateSearchFilter ( {
69- filters,
70- } ) ;
71- } ,
72- [ updateSearchFilter ] ,
73- ) ;
74-
75- const memoizedContent = useMemo ( ( ) => {
76- if ( isLoading ) return < LoadingState /> ;
77- if ( error ) return < ErrorState message = { ( error as Error ) . message } /> ;
78- if ( ! componentLibrary ) return < EmptyState /> ;
79-
80- if ( ! remoteComponentLibrarySearchEnabled && searchResult ) {
81- // If there's a search result, use the SearchResults component
82- return (
83- < SearchResults
84- searchResult = { searchResult }
85- onFiltersChange = { handleFiltersChange }
86- />
87- ) ;
88- }
89-
90- // Otherwise show the regular folder structure
91- const hasUsedComponents =
92- usedComponentsFolder ?. components &&
93- usedComponentsFolder . components . length > 0 ;
94-
95- const hasFavouriteComponents =
96- favoritesFolder ?. components && favoritesFolder . components . length > 0 ;
97-
98- const hasUserComponents =
99- userComponentsFolder ?. components &&
100- userComponentsFolder . components . length > 0 ;
101-
102- return (
103- < BlockStack gap = "2" >
104- { remoteComponentLibrarySearchEnabled && < UpgradeAvailableAlertBox /> }
105-
106- < BlockStack >
107- { hasUsedComponents && (
108- < FolderItem
109- key = "used-components-folder"
110- folder = { usedComponentsFolder }
111- icon = "LayoutGrid"
112- />
113- ) }
114- { hasFavouriteComponents && (
115- < FolderItem
116- key = "favorite-components-folder"
117- folder = { favoritesFolder }
118- icon = "Star"
119- />
120- ) }
121- { hasUserComponents && (
122- < FolderItem
123- key = "my-components-folder"
124- folder = { userComponentsFolder }
125- icon = "Puzzle"
126- />
127- ) }
128- < Separator />
129- < FolderItem
130- key = "graph-inputs-outputs-folder"
131- folder = {
132- {
133- name : "Inputs & Outputs" ,
134- components : [
135- < IONodeSidebarItem key = "input" nodeType = "input" /> ,
136- < IONodeSidebarItem key = "output" nodeType = "output" /> ,
137- ] ,
138- folders : [ ] ,
139- } as UIComponentFolder
140- }
141- icon = "Cable"
142- />
143- < Separator />
144- < FolderItem
145- key = "standard-library-folder"
146- folder = {
147- {
148- name : "Standard library" ,
149- components : [ ] ,
150- folders : componentLibrary . folders ,
151- } as UIComponentFolder
152- }
153- icon = "Folder"
154- />
155- { githubComponentLibraryEnabled && (
156- < >
157- < Separator />
158- < BlockStack gap = "1" className = "pl-2 py-2" >
159- < InlineStack className = "w-full" align = "space-between" >
160- < Text size = "sm" tone = "subdued" >
161- Connected libraries
162- </ Text >
163- < ManageLibrariesDialog />
164- </ InlineStack >
165-
166- { existingComponentLibraries ?. length === 0 && (
167- < BlockStack gap = "1" align = "center" >
168- < Text size = "sm" tone = "subdued" >
169- No libraries connected
170- </ Text >
171- </ BlockStack >
172- ) }
173- </ BlockStack >
174-
175- { existingComponentLibraries ?. map ( ( library ) => (
176- < LibraryFolderItem
177- key = { library . id }
178- library = { getComponentLibrary ( library . id ) }
179- icon = { library . icon as any /** todo: fix this */ }
180- />
181- ) ) }
182- </ >
183- ) }
184- </ BlockStack >
185- </ BlockStack >
186- ) ;
187- } , [
188- componentLibrary ,
189- usedComponentsFolder ,
190- userComponentsFolder ,
191- favoritesFolder ,
192- isLoading ,
193- error ,
194- searchResult ,
195- remoteComponentLibrarySearchEnabled ,
196- githubComponentLibraryEnabled ,
197- existingComponentLibraries ,
198- getComponentLibrary ,
199- ] ) ;
51+ const handleFiltersChange = ( filters : string [ ] ) => {
52+ updateSearchFilter ( {
53+ filters,
54+ } ) ;
55+ } ;
20056
20157 if ( ! isOpen ) {
20258 return (
@@ -223,7 +79,9 @@ const GraphComponents = ({ isOpen }: { isOpen: boolean }) => {
22379 }
22480
22581 const searchComponent = remoteComponentLibrarySearchEnabled ? (
226- < PublishedComponentsSearch > { memoizedContent } </ PublishedComponentsSearch >
82+ < PublishedComponentsSearch >
83+ < ComponentLibrarySection />
84+ </ PublishedComponentsSearch >
22785 ) : (
22886 < >
22987 < SearchInput
@@ -233,7 +91,7 @@ const GraphComponents = ({ isOpen }: { isOpen: boolean }) => {
23391 onFiltersChange = { handleFiltersChange }
23492 />
23593
236- { memoizedContent }
94+ < ComponentLibrarySection />
23795 </ >
23896 ) ;
23997
@@ -259,4 +117,146 @@ const GraphComponents = ({ isOpen }: { isOpen: boolean }) => {
259117 ) ;
260118} ;
261119
120+ function ComponentLibrarySection ( ) {
121+ const remoteComponentLibrarySearchEnabled = useBetaFlagValue (
122+ "remote-component-library-search" ,
123+ ) ;
124+
125+ const githubComponentLibraryEnabled = useBetaFlagValue (
126+ "github-component-library" ,
127+ ) ;
128+
129+ const { getComponentLibrary, existingComponentLibraries } =
130+ useComponentLibrary ( ) ;
131+
132+ const { updateSearchFilter } = useForcedSearchContext ( ) ;
133+ const {
134+ componentLibrary,
135+ usedComponentsFolder,
136+ userComponentsFolder,
137+ favoritesFolder,
138+ isLoading,
139+ error,
140+ searchResult,
141+ } = useComponentLibrary ( ) ;
142+
143+ const handleFiltersChange = ( filters : string [ ] ) => {
144+ updateSearchFilter ( {
145+ filters,
146+ } ) ;
147+ } ;
148+
149+ if ( isLoading ) return < LoadingState /> ;
150+ if ( error ) return < ErrorState message = { ( error as Error ) . message } /> ;
151+ if ( ! componentLibrary ) return < EmptyState /> ;
152+
153+ if ( ! remoteComponentLibrarySearchEnabled && searchResult ) {
154+ // If there's a search result, use the SearchResults component
155+ return (
156+ < SearchResults
157+ searchResult = { searchResult }
158+ onFiltersChange = { handleFiltersChange }
159+ />
160+ ) ;
161+ }
162+
163+ // Otherwise show the regular folder structure
164+ const hasUsedComponents =
165+ usedComponentsFolder ?. components &&
166+ usedComponentsFolder . components . length > 0 ;
167+
168+ const hasFavouriteComponents =
169+ favoritesFolder ?. components && favoritesFolder . components . length > 0 ;
170+
171+ const hasUserComponents =
172+ userComponentsFolder ?. components &&
173+ userComponentsFolder . components . length > 0 ;
174+
175+ return (
176+ < BlockStack gap = "2" >
177+ { remoteComponentLibrarySearchEnabled && < UpgradeAvailableAlertBox /> }
178+
179+ < BlockStack >
180+ { hasUsedComponents && (
181+ < FolderItem
182+ key = "used-components-folder"
183+ folder = { usedComponentsFolder }
184+ icon = "LayoutGrid"
185+ />
186+ ) }
187+ { hasFavouriteComponents && (
188+ < FolderItem
189+ key = "favorite-components-folder"
190+ folder = { favoritesFolder }
191+ icon = "Star"
192+ />
193+ ) }
194+ { hasUserComponents && (
195+ < FolderItem
196+ key = "my-components-folder"
197+ folder = { userComponentsFolder }
198+ icon = "Puzzle"
199+ />
200+ ) }
201+ < Separator />
202+ < FolderItem
203+ key = "graph-inputs-outputs-folder"
204+ folder = {
205+ {
206+ name : "Inputs & Outputs" ,
207+ components : [
208+ < IONodeSidebarItem key = "input" nodeType = "input" /> ,
209+ < IONodeSidebarItem key = "output" nodeType = "output" /> ,
210+ ] ,
211+ folders : [ ] ,
212+ } as UIComponentFolder
213+ }
214+ icon = "Cable"
215+ />
216+ < Separator />
217+ < FolderItem
218+ key = "standard-library-folder"
219+ folder = {
220+ {
221+ name : "Standard library" ,
222+ components : [ ] ,
223+ folders : componentLibrary . folders ,
224+ } as UIComponentFolder
225+ }
226+ icon = "Folder"
227+ />
228+ { githubComponentLibraryEnabled && (
229+ < >
230+ < Separator />
231+ < BlockStack gap = "1" className = "pl-2 py-2" >
232+ < InlineStack className = "w-full" align = "space-between" >
233+ < Text size = "sm" tone = "subdued" >
234+ Connected libraries
235+ </ Text >
236+ < ManageLibrariesDialog />
237+ </ InlineStack >
238+
239+ { existingComponentLibraries ?. length === 0 && (
240+ < BlockStack gap = "1" align = "center" >
241+ < Text size = "sm" tone = "subdued" >
242+ No libraries connected
243+ </ Text >
244+ </ BlockStack >
245+ ) }
246+ </ BlockStack >
247+
248+ { existingComponentLibraries ?. map ( ( library ) => (
249+ < LibraryFolderItem
250+ key = { library . id }
251+ library = { getComponentLibrary ( library . id ) }
252+ icon = { library . icon as any /** todo: fix this */ }
253+ />
254+ ) ) }
255+ </ >
256+ ) }
257+ </ BlockStack >
258+ </ BlockStack >
259+ ) ;
260+ }
261+
262262export default GraphComponents ;
0 commit comments