@@ -48,6 +48,7 @@ export const ProjectSettings: React.FC = () => {
4848 const params = useParams ( ) ;
4949 const navigate = useNavigate ( ) ;
5050 const paramProjectName = params . projectName ?? '' ;
51+ const [ isExpandedCliSection , setIsExpandedCliSection ] = React . useState ( false ) ;
5152 const [ configCliCommand , copyCliCommand ] = useConfigProjectCliCommand ( { projectName : paramProjectName } ) ;
5253
5354 const { isAvailableDeletingPermission, isProjectManager, isProjectAdmin, isAvailableProjectManaging } =
@@ -61,6 +62,15 @@ export const ProjectSettings: React.FC = () => {
6162
6263 const { data, isLoading, error } = useGetProjectQuery ( { name : paramProjectName } ) ;
6364
65+ const { data : runsData } = useGetRunsQuery ( {
66+ project_name : paramProjectName ,
67+ limit : 1 ,
68+ } ) ;
69+
70+ useEffect ( ( ) => {
71+ setIsExpandedCliSection ( ! runsData || runsData . length === 0 ) ;
72+ } , [ runsData ] ) ;
73+
6474 useEffect ( ( ) => {
6575 if ( error && 'status' in error && error . status === 404 ) {
6676 riseRouterException ( ) ;
@@ -170,15 +180,6 @@ export const ProjectSettings: React.FC = () => {
170180
171181 const [ activeStepIndex , setActiveStepIndex ] = React . useState ( 0 ) ;
172182
173- const { data : runsData } = useGetRunsQuery ( {
174- limit : 1 ,
175- } ) ;
176- const [ expanded , setExpanded ] = React . useState ( false ) ;
177-
178- useEffect ( ( ) => {
179- setExpanded ( ! runsData || runsData . length === 0 ) ;
180- } , [ runsData ] ) ;
181-
182183 if ( isLoadingPage )
183184 return (
184185 < Container >
@@ -194,13 +195,13 @@ export const ProjectSettings: React.FC = () => {
194195 < ExpandableSection
195196 variant = "container"
196197 headerText = "CLI"
197- expanded = { expanded }
198- onChange = { ( { detail } ) => setExpanded ( detail . expanded ) }
198+ expanded = { isExpandedCliSection }
199+ onChange = { ( { detail } ) => setIsExpandedCliSection ( detail . expanded ) }
199200 headerActions = {
200201 < Button
201202 iconName = "script"
202- variant = { expanded ? 'normal' : 'primary' }
203- onClick = { ( ) => setExpanded ( ( prev ) => ! prev ) }
203+ variant = { isExpandedCliSection ? 'normal' : 'primary' }
204+ onClick = { ( ) => setIsExpandedCliSection ( ( prev ) => ! prev ) }
204205 />
205206 }
206207 // headerInfo={<InfoLink onFollow={() => openHelpPanel(CLI_INFO)} />}
@@ -218,7 +219,7 @@ export const ProjectSettings: React.FC = () => {
218219 } }
219220 onNavigate = { ( { detail } ) => setActiveStepIndex ( detail . requestedStepIndex ) }
220221 activeStepIndex = { activeStepIndex }
221- onSubmit = { ( ) => setExpanded ( false ) }
222+ onSubmit = { ( ) => setIsExpandedCliSection ( false ) }
222223 submitButtonText = "Dismiss"
223224 allowSkipTo = { true }
224225 steps = { [
@@ -227,81 +228,87 @@ export const ProjectSettings: React.FC = () => {
227228 // info: <InfoLink onFollow={() => openHelpPanel(CLI_INFO)} />,
228229 description : 'To use dstack, install the CLI on your local machine.' ,
229230 content : (
230- < Tabs
231- variant = "stacked"
232- tabs = { [
233- {
234- label : 'uv' ,
235- id : 'uv' ,
236- content : (
237- < >
238- < div className = { styles . codeWrapper } >
239- < Code className = { styles . code } >
240- uv tool install dstack -U
241- </ Code >
242-
243- < div className = { styles . copy } >
244- < Popover
245- dismissButton = { false }
246- position = "top"
247- size = "small"
248- triggerType = "custom"
249- content = {
250- < StatusIndicator type = "success" >
251- { t ( 'common.copied' ) }
252- </ StatusIndicator >
253- }
254- >
255- < Button
256- formAction = "none"
257- iconName = "copy"
258- variant = "normal"
259- onClick = { ( ) =>
260- copyToClipboard ( 'uv tool install dstack -U' )
231+ < Hotspot hotspotId = { HotspotIds . INSTALL_CLI_COMMAND } >
232+ < Tabs
233+ variant = "stacked"
234+ tabs = { [
235+ {
236+ label : 'uv' ,
237+ id : 'uv' ,
238+ content : (
239+ < >
240+ < div className = { styles . codeWrapper } >
241+ < Code className = { styles . code } >
242+ uv tool install dstack -U
243+ </ Code >
244+
245+ < div className = { styles . copy } >
246+ < Popover
247+ dismissButton = { false }
248+ position = "top"
249+ size = "small"
250+ triggerType = "custom"
251+ content = {
252+ < StatusIndicator type = "success" >
253+ { t ( 'common.copied' ) }
254+ </ StatusIndicator >
261255 }
262- />
263- </ Popover >
256+ >
257+ < Button
258+ formAction = "none"
259+ iconName = "copy"
260+ variant = "normal"
261+ onClick = { ( ) =>
262+ copyToClipboard (
263+ 'uv tool install dstack -U' ,
264+ )
265+ }
266+ />
267+ </ Popover >
268+ </ div >
264269 </ div >
265- </ div >
266- </ >
267- ) ,
268- } ,
269- {
270- label : 'pip' ,
271- id : 'pip' ,
272- content : (
273- < >
274- < div className = { styles . codeWrapper } >
275- < Code className = { styles . code } > pip install dstack -U</ Code >
276-
277- < div className = { styles . copy } >
278- < Popover
279- dismissButton = { false }
280- position = "top"
281- size = "small"
282- triggerType = "custom"
283- content = {
284- < StatusIndicator type = "success" >
285- { t ( 'common.copied' ) }
286- </ StatusIndicator >
287- }
288- >
289- < Button
290- formAction = "none"
291- iconName = "copy"
292- variant = "normal"
293- onClick = { ( ) =>
294- copyToClipboard ( 'pip install dstack -U' )
270+ </ >
271+ ) ,
272+ } ,
273+ {
274+ label : 'pip' ,
275+ id : 'pip' ,
276+ content : (
277+ < >
278+ < div className = { styles . codeWrapper } >
279+ < Code className = { styles . code } >
280+ pip install dstack -U
281+ </ Code >
282+
283+ < div className = { styles . copy } >
284+ < Popover
285+ dismissButton = { false }
286+ position = "top"
287+ size = "small"
288+ triggerType = "custom"
289+ content = {
290+ < StatusIndicator type = "success" >
291+ { t ( 'common.copied' ) }
292+ </ StatusIndicator >
295293 }
296- />
297- </ Popover >
294+ >
295+ < Button
296+ formAction = "none"
297+ iconName = "copy"
298+ variant = "normal"
299+ onClick = { ( ) =>
300+ copyToClipboard ( 'pip install dstack -U' )
301+ }
302+ />
303+ </ Popover >
304+ </ div >
298305 </ div >
299- </ div >
300- </ >
301- ) ,
302- } ,
303- ] }
304- / >
306+ </ >
307+ ) ,
308+ } ,
309+ ] }
310+ />
311+ </ Hotspot >
305312 ) ,
306313 isOptional : true ,
307314 } ,
0 commit comments