@@ -2,12 +2,15 @@ import React from 'react';
22import { useTranslation } from 'react-i18next' ;
33import { useNavigate } from 'react-router-dom' ;
44import { ButtonDropdownProps } from '@cloudscape-design/components' ;
5+ import { ButtonProps } from '@cloudscape-design/components/button' ;
56
6- import { Button , ButtonDropdown , Header , Loader , PropertyFilter , SpaceBetween , Table , Toggle } from 'components' ;
7+ import { Alert , Button , ButtonDropdown , Header , Loader , PropertyFilter , SpaceBetween , Table , Toggle } from 'components' ;
78
89import { DEFAULT_TABLE_PAGE_SIZE } from 'consts' ;
910import { useBreadcrumbs , useCollection , useInfiniteScroll } from 'hooks' ;
11+ import { goToUrl } from 'libs' ;
1012import { ROUTES } from 'routes' ;
13+ import { useGetFleetsQuery } from 'services/fleet' ;
1114import { useLazyGetRunsQuery } from 'services/run' ;
1215
1316import { useRunListPreferences } from './Preferences/useRunListPreferences' ;
@@ -49,6 +52,8 @@ export const RunList: React.FC = () => {
4952 localStorePrefix : 'administration-run-list-page' ,
5053 } ) ;
5154
55+ const { data : fleetsData , isLoading : isLoadingFleets } = useGetFleetsQuery ( { limit : 1 } ) ;
56+
5257 const { data, isLoading, refreshList, isLoadingMore } = useInfiniteScroll < IRun , TRunsRequestParams > ( {
5358 useLazyQuery : useLazyGetRunsQuery ,
5459 args : { ...filteringRequestParams , limit : DEFAULT_TABLE_PAGE_SIZE , job_submissions_limit : 1 } ,
@@ -117,6 +122,13 @@ export const RunList: React.FC = () => {
117122 }
118123 } ;
119124
125+ const noFleets = ! isLoadingFleets && ! fleetsData ?. length ;
126+
127+ const onCreateAFleet : ButtonProps [ 'onClick' ] = ( event ) => {
128+ event . preventDefault ( ) ;
129+ goToUrl ( 'https://dstack.ai/docs/quickstart/#create-a-fleet' , true ) ;
130+ } ;
131+
120132 return (
121133 < Table
122134 { ...collectionProps }
@@ -130,50 +142,69 @@ export const RunList: React.FC = () => {
130142 columnDisplay = { preferences . contentDisplay }
131143 preferences = { < Preferences /> }
132144 header = {
133- < Header
134- variant = "awsui-h1-sticky"
135- actions = {
136- < SpaceBetween size = "xs" direction = "horizontal" >
137- < ButtonDropdown
138- items = { [
139- {
140- text : 'Dev environment' ,
141- id : 'dev_env' ,
142- href : `${ ROUTES . RUNS . CREATE_DEV_ENV } ${
143- filteringRequestParams . project_name
144- ? `?project_name=${ filteringRequestParams . project_name } `
145- : ''
146- } `,
147- } ,
148- ] }
149- onItemFollow = { onFollowButtonDropdownLink }
145+ < >
146+ { noFleets && (
147+ < div className = { styles . alertBox } >
148+ < Alert
149+ header = { t ( 'fleets.no_alert.title' ) }
150+ type = "info"
151+ action = {
152+ < Button iconName = "external" formAction = "none" onClick = { onCreateAFleet } >
153+ { t ( 'fleets.no_alert.button_title' ) }
154+ </ Button >
155+ }
150156 >
151- { t ( 'common.new' ) }
152- </ ButtonDropdown >
153-
154- < Button formAction = "none" onClick = { abortClickHandle } disabled = { isDisabledAbortButton } >
155- { t ( 'common.abort' ) }
156- </ Button >
157-
158- < Button formAction = "none" onClick = { stopClickHandle } disabled = { isDisabledStopButton } >
159- { t ( 'common.stop' ) }
160- </ Button >
161-
162- { /*<Button formAction="none" onClick={deleteClickHandle} disabled={isDisabledDeleteButton}>*/ }
163- { /* {t('common.delete')}*/ }
164- { /*</Button>*/ }
165-
166- < Button
167- iconName = "refresh"
168- disabled = { isLoading }
169- ariaLabel = { t ( 'common.refresh' ) }
170- onClick = { refreshList }
171- />
172- </ SpaceBetween >
173- }
174- >
175- { t ( 'projects.runs' ) }
176- </ Header >
157+ { t ( 'fleets.no_alert.description' ) }
158+ </ Alert >
159+ </ div >
160+ ) }
161+
162+ < Header
163+ variant = "awsui-h1-sticky"
164+ actions = {
165+ < SpaceBetween size = "xs" direction = "horizontal" >
166+ < ButtonDropdown
167+ disabled = { ! fleetsData ?. length }
168+ items = { [
169+ {
170+ text : 'Dev environment' ,
171+ id : 'dev_env' ,
172+ href : `${ ROUTES . RUNS . CREATE_DEV_ENV } ${
173+ filteringRequestParams . project_name
174+ ? `?project_name=${ filteringRequestParams . project_name } `
175+ : ''
176+ } `,
177+ } ,
178+ ] }
179+ onItemFollow = { onFollowButtonDropdownLink }
180+ >
181+ { t ( 'common.new' ) }
182+ </ ButtonDropdown >
183+
184+ < Button formAction = "none" onClick = { abortClickHandle } disabled = { isDisabledAbortButton } >
185+ { t ( 'common.abort' ) }
186+ </ Button >
187+
188+ < Button formAction = "none" onClick = { stopClickHandle } disabled = { isDisabledStopButton } >
189+ { t ( 'common.stop' ) }
190+ </ Button >
191+
192+ { /*<Button formAction="none" onClick={deleteClickHandle} disabled={isDisabledDeleteButton}>*/ }
193+ { /* {t('common.delete')}*/ }
194+ { /*</Button>*/ }
195+
196+ < Button
197+ iconName = "refresh"
198+ disabled = { isLoading }
199+ ariaLabel = { t ( 'common.refresh' ) }
200+ onClick = { refreshList }
201+ />
202+ </ SpaceBetween >
203+ }
204+ >
205+ { t ( 'projects.runs' ) }
206+ </ Header >
207+ </ >
177208 }
178209 filter = {
179210 < div className = { styles . selectFilters } >
0 commit comments