11import { FolderExplorerHeaderFragment$key } from '../__generated__/FolderExplorerHeaderFragment.graphql' ;
2- import { PrimaryAppOption } from './ComputeSessionNodeItems/SessionActionButtons' ;
32import EditableVFolderName from './EditableVFolderName' ;
3+ import FileBrowserButton from './FileBrowserButton' ;
44import VFolderNodeIdenticon from './VFolderNodeIdenticon' ;
5- import { Button , Tooltip , Image , Grid , theme , Typography , App } from 'antd' ;
6- import { BAIButton , BAIFlex , useErrorMessageResolver } from 'backend.ai-ui' ;
5+ import { Button , Tooltip , Image , Grid , theme , Typography } from 'antd' ;
6+ import { BAIFlex } from 'backend.ai-ui' ;
77import _ from 'lodash' ;
8- import React , { LegacyRef } from 'react' ;
8+ import React , { Ref } from 'react' ;
99import { useTranslation } from 'react-i18next' ;
10- import {
11- fetchQuery ,
12- graphql ,
13- useFragment ,
14- useRelayEnvironment ,
15- } from 'react-relay' ;
16- import { FolderExplorerHeader_ImageQuery } from 'src/__generated__/FolderExplorerHeader_ImageQuery.graphql' ;
17- import { getImageFullName } from 'src/helper' ;
18- import { useSuspendedBackendaiClient } from 'src/hooks' ;
19- import {
20- StartSessionWithDefaultValue ,
21- useStartSession ,
22- } from 'src/hooks/useStartSession' ;
10+ import { graphql , useFragment } from 'react-relay' ;
2311
2412interface FolderExplorerHeaderProps {
2513 vfolderNodeFrgmt ?: FolderExplorerHeaderFragment$key | null ;
26- folderExplorerRef : LegacyRef < HTMLDivElement > ;
14+ folderExplorerRef : Ref < HTMLDivElement > ;
2715 titleStyle ?: React . CSSProperties ;
2816}
2917
@@ -37,13 +25,6 @@ const FolderExplorerHeader: React.FC<FolderExplorerHeaderProps> = ({
3725 const { t } = useTranslation ( ) ;
3826 const { token } = theme . useToken ( ) ;
3927 const { lg } = Grid . useBreakpoint ( ) ;
40- const { message, modal } = App . useApp ( ) ;
41-
42- const relayEnv = useRelayEnvironment ( ) ;
43- const baiClient = useSuspendedBackendaiClient ( ) ;
44- const { getErrorMessage } = useErrorMessageResolver ( ) ;
45- const { startSessionWithDefault, upsertSessionNotification } =
46- useStartSession ( ) ;
4728
4829 const vfolderNode = useFragment (
4930 graphql `
@@ -56,6 +37,7 @@ const FolderExplorerHeader: React.FC<FolderExplorerHeaderProps> = ({
5637 ...VFolderNameTitleNodeFragment
5738 ...VFolderNodeIdenticonFragment
5839 ...EditableVFolderNameFragment
40+ ...FileBrowserButtonFragment
5941 }
6042 ` ,
6143 vfolderNodeFrgmt ,
@@ -117,140 +99,9 @@ const FolderExplorerHeader: React.FC<FolderExplorerHeaderProps> = ({
11799 justify = "end"
118100 gap = { token . marginSM }
119101 >
120- { ! vfolderNode ?. unmanaged_path ? (
102+ { ! vfolderNode ?. unmanaged_path && vfolderNode ? (
121103 < >
122- < Tooltip title = { ! lg && t ( 'data.explorer.ExecuteFileBrowser' ) } >
123- < BAIButton
124- icon = {
125- < Image
126- width = "18px"
127- src = "/resources/icons/filebrowser.svg"
128- alt = "File Browser"
129- preview = { false }
130- />
131- }
132- action = { async ( ) => {
133- // FIXME: Currently, file browser filtering by server-side is not supported.
134- await fetchQuery < FolderExplorerHeader_ImageQuery > (
135- relayEnv ,
136- graphql `
137- query FolderExplorerHeader_ImageQuery(
138- $installed: Boolean
139- ) {
140- images(is_installed: $installed) {
141- id
142- tag
143- registry
144- architecture
145- name @deprecatedSince(version: "24.12.0")
146- namespace @since(version: "24.12.0")
147- labels {
148- key
149- value
150- }
151- tags @since(version: "24.12.0") {
152- key
153- value
154- }
155- }
156- }
157- ` ,
158- {
159- installed : true ,
160- } ,
161- {
162- fetchPolicy : 'store-or-network' ,
163- } ,
164- )
165- . toPromise ( )
166- . then ( ( response ) =>
167- response ?. images ?. filter ( ( image ) =>
168- image ?. labels ?. find (
169- ( label ) =>
170- label ?. key === 'ai.backend.service-ports' &&
171- label ?. value ?. toLowerCase ( ) . includes ( 'filebrowser' ) ,
172- ) ,
173- ) ,
174- )
175- . then ( async ( filebrowserImages ) => {
176- if ( _ . isEmpty ( filebrowserImages ) ) {
177- message . error (
178- t ( 'data.explorer.NoImagesSupportingFileBrowser' ) ,
179- ) ;
180- return ;
181- }
182-
183- const fileBrowserFormValue : StartSessionWithDefaultValue =
184- {
185- sessionName : `filebrowser-${ vfolderNode ?. row_id . split ( '-' ) [ 0 ] } ` ,
186- sessionType : 'interactive' ,
187- // use default file browser image if configured and allowed
188- ...( baiClient . _config ?. defaultFileBrowserImage &&
189- baiClient . _config ?. allow_manual_image_name_for_session
190- ? {
191- environments : {
192- manual :
193- baiClient . _config . defaultFileBrowserImage ,
194- } ,
195- }
196- : // otherwise use the first image found
197- {
198- environments : {
199- version :
200- getImageFullName ( filebrowserImages ?. [ 0 ] ) ||
201- '' ,
202- } ,
203- } ) ,
204- allocationPreset : 'minimum-required' ,
205- cluster_mode : 'single-node' ,
206- cluster_size : 1 ,
207- mount_ids : [
208- vfolderNode ?. row_id ?. replaceAll ( '-' , '' ) || '' ,
209- ] ,
210- resource : {
211- cpu : 1 ,
212- mem : '0.5g' ,
213- } ,
214- } ;
215-
216- await startSessionWithDefault ( fileBrowserFormValue )
217- . then ( ( results ) => {
218- if (
219- results ?. fulfilled &&
220- results . fulfilled . length > 0
221- ) {
222- upsertSessionNotification ( results . fulfilled , [
223- {
224- extraData : {
225- appName : 'filebrowser' ,
226- } as PrimaryAppOption ,
227- } ,
228- ] ) ;
229- }
230- if (
231- results ?. rejected &&
232- results . rejected . length > 0
233- ) {
234- const error = results . rejected [ 0 ] . reason ;
235- modal . error ( {
236- title : error ?. title ,
237- content : getErrorMessage ( error ) ,
238- } ) ;
239- }
240- } )
241- . catch ( ( error ) => {
242- console . error (
243- 'Unexpected error during session creation:' ,
244- error ,
245- ) ;
246- message . error ( t ( 'error.UnexpectedError' ) ) ;
247- } ) ;
248- } ) ;
249- } }
250- >
251- { lg && t ( 'data.explorer.ExecuteFileBrowser' ) }
252- </ BAIButton >
253- </ Tooltip >
104+ < FileBrowserButton vfolderFrgmt = { vfolderNode } showTitle = { lg } />
254105 < Tooltip title = { ! lg && t ( 'data.explorer.RunSSH/SFTPserver' ) } >
255106 < Button
256107 icon = {
0 commit comments