@@ -20,8 +20,8 @@ import {
2020  PaginationPrevious , 
2121}  from  '@/components/ui/pagination' ; 
2222import  {  CodeEditor  }  from  '@/components/CodeEditor' ; 
23- 
2423import  {  trpc  }  from  '@/api/trpc' ; 
24+ import  {  cn  }  from  '@/utils/style' ; 
2525import  {  defaultErrorHandler  }  from  '@/api/trpc' ; 
2626import  { 
2727  LuPlay , 
@@ -32,7 +32,10 @@ import {
3232  LuRefreshCw , 
3333  LuExternalLink , 
3434  LuCopy , 
35+   LuMinimize2 , 
36+   LuMaximize2 , 
3537}  from  'react-icons/lu' ; 
38+ import  {  useLocalStorageState  }  from  'ahooks' ; 
3639import  {  AlertConfirm  }  from  '@/components/AlertConfirm' ; 
3740import  {  Loading  }  from  '@/components/Loading' ; 
3841import  {  ErrorTip  }  from  '@/components/ErrorTip' ; 
@@ -82,6 +85,10 @@ function PageComponent() {
8285  const  [ activePreviewParams ,  setActivePreviewParams ]  =  useState < UrlParam [ ] > ( [ 
8386    {  key : '' ,  value : ''  } , 
8487  ] ) ; 
88+   const  [ isPreviewCollapsed  =  false ,  setPreviewCollapsed ]  = 
89+     useLocalStorageState < boolean > ( `worker-preview-collapsed-${ workerId }  ,  { 
90+       defaultValue : false , 
91+     } ) ; 
8592  const  trpcUtils  =  trpc . useUtils ( ) ; 
8693
8794  const  { 
@@ -189,6 +196,10 @@ function PageComponent() {
189196    setPreviewKey ( ( prev )  =>  prev  +  1 ) ; 
190197  } ) ; 
191198
199+   const  handleTogglePreviewCollapse  =  useEvent ( ( )  =>  { 
200+     setPreviewCollapsed ( ( prev )  =>  ! prev ) ; 
201+   } ) ; 
202+ 
192203  const  handlePreviewLoad  =  useEvent ( ( )  =>  { 
193204    setIsLoadingPreview ( false ) ; 
194205  } ) ; 
@@ -306,10 +317,29 @@ function PageComponent() {
306317          </ TabsList > 
307318
308319          < TabsContent  value = "code"  className = "flex flex-1 flex-col space-y-4" > 
309-             < div  className = "grid flex-1 grid-cols-1 gap-4 lg:grid-cols-2" > 
320+             < div 
321+               className = { cn ( 'grid flex-1 grid-cols-1 gap-4' ,  { 
322+                 'lg:grid-cols-2' : ! isPreviewCollapsed , 
323+               } ) } 
324+             > 
310325              < Card  className = "flex flex-col" > 
311-                 < CardHeader > 
326+                 < CardHeader   className = "flex flex-row items-center justify-between space-y-0" > 
312327                  < CardTitle > { t ( 'Worker Code' ) } </ CardTitle > 
328+                   < SimpleTooltip 
329+                     content = { 
330+                       isPreviewCollapsed 
331+                         ? t ( 'Expand Preview' ) 
332+                         : t ( 'Collapse Preview' ) 
333+                     } 
334+                   > 
335+                     < Button 
336+                       variant = "outline" 
337+                       size = "icon" 
338+                       Icon = { isPreviewCollapsed  ? LuMinimize2  : LuMaximize2 } 
339+                       onClick = { handleTogglePreviewCollapse } 
340+                       className = "h-8 w-8" 
341+                     /> 
342+                   </ SimpleTooltip > 
313343                </ CardHeader > 
314344                < CardContent  className = "flex-1" > 
315345                  < CodeEditor 
@@ -321,89 +351,95 @@ function PageComponent() {
321351                </ CardContent > 
322352              </ Card > 
323353
324-               < Card  className = "flex flex-col" > 
325-                 < CardHeader  className = "flex flex-row items-center justify-between space-y-0" > 
326-                   < CardTitle > { t ( 'Preview' ) } </ CardTitle > 
327-                   < div  className = "flex items-center space-x-2" > 
328-                     < SimpleTooltip  content = { t ( 'Copy API URL' ) } > 
329-                       < Button 
330-                         variant = "outline" 
331-                         size = "icon" 
332-                         Icon = { LuCopy } 
333-                         onClick = { handleCopyUrl } 
334-                         className = "h-8 w-8" 
335-                       /> 
336-                     </ SimpleTooltip > 
337-                     < SimpleTooltip  content = { t ( 'Open in New Window' ) } > 
338-                       < Button 
339-                         variant = "outline" 
340-                         size = "icon" 
341-                         Icon = { LuExternalLink } 
342-                         onClick = { handleOpenInNewWindow } 
343-                         disabled = { ! worker . active } 
344-                         className = "h-8 w-8" 
345-                       /> 
346-                     </ SimpleTooltip > 
347-                     < SimpleTooltip  content = { t ( 'Execute Preview' ) } > 
348-                       < Button 
349-                         variant = "outline" 
350-                         size = "icon" 
351-                         Icon = { LuPlay } 
352-                         onClick = { handleExecutePreview } 
353-                         loading = { isLoadingPreview } 
354-                         disabled = { ! worker . active } 
355-                         className = "h-8 w-8" 
356-                       /> 
357-                     </ SimpleTooltip > 
358-                   </ div > 
359-                 </ CardHeader > 
360-                 < CardContent  className = "flex flex-1 flex-col" > 
361-                   < UrlParamsInput 
362-                     params = { previewParams } 
363-                     onChange = { setPreviewParams } 
364-                   /> 
365- 
366-                   { previewKey  >  0  ? ( 
367-                     < div  className = "flex h-full flex-1 flex-col space-y-4" > 
368-                       < p  className = "text-muted-foreground text-sm" > 
369-                         { t ( 'Live preview of the worker API endpoint:' ) } 
370-                       </ p > 
371-                       < div  className = "relative h-full flex-1 rounded-md border bg-white" > 
372-                         { isLoadingPreview  &&  ( 
373-                           < div  className = "bg-background/80 absolute inset-0 z-10 flex items-center justify-center rounded-md backdrop-blur-sm" > 
374-                             < div  className = "flex items-center space-x-2" > 
375-                               < div  className = "border-primary h-4 w-4 animate-spin rounded-full border-b-2"  /> 
376-                               < span  className = "text-sm" > { t ( 'Loading...' ) } </ span > 
377-                             </ div > 
378-                           </ div > 
379-                         ) } 
380-                         < iframe 
381-                           key = { previewKey } 
382-                           src = { `${ window . location . origin } ${ workspaceId } ${ workerId } ${ getQueryString ( activePreviewParams )  ? `?${ getQueryString ( activePreviewParams ) }   : '' }  } 
383-                           className = "h-full w-full rounded-md" 
384-                           title = "Worker Preview" 
385-                           sandbox = "allow-same-origin allow-scripts" 
386-                           onLoad = { handlePreviewLoad } 
354+               { ! isPreviewCollapsed  &&  ( 
355+                 < Card  className = "flex flex-col" > 
356+                   < CardHeader  className = "flex flex-row items-center justify-between space-y-0" > 
357+                     < CardTitle > { t ( 'Preview' ) } </ CardTitle > 
358+                     < div  className = "flex items-center space-x-2" > 
359+                       < SimpleTooltip  content = { t ( 'Copy API URL' ) } > 
360+                         < Button 
361+                           variant = "outline" 
362+                           size = "icon" 
363+                           Icon = { LuCopy } 
364+                           onClick = { handleCopyUrl } 
365+                           className = "h-8 w-8" 
387366                        /> 
388-                       </ div > 
367+                       </ SimpleTooltip > 
368+                       < SimpleTooltip  content = { t ( 'Open in New Window' ) } > 
369+                         < Button 
370+                           variant = "outline" 
371+                           size = "icon" 
372+                           Icon = { LuExternalLink } 
373+                           onClick = { handleOpenInNewWindow } 
374+                           disabled = { ! worker . active } 
375+                           className = "h-8 w-8" 
376+                         /> 
377+                       </ SimpleTooltip > 
378+                       < SimpleTooltip  content = { t ( 'Execute Preview' ) } > 
379+                         < Button 
380+                           variant = "outline" 
381+                           size = "icon" 
382+                           Icon = { LuPlay } 
383+                           onClick = { handleExecutePreview } 
384+                           loading = { isLoadingPreview } 
385+                           disabled = { ! worker . active } 
386+                           className = "h-8 w-8" 
387+                         /> 
388+                       </ SimpleTooltip > 
389389                    </ div > 
390-                   )  : ( 
391-                     < div  className = "text-muted-foreground flex h-[400px] items-center justify-center" > 
392-                       < div  className = "space-y-2 text-center" > 
393-                         < LuPlay  className = "mx-auto h-12 w-12"  /> 
394-                         < p > 
395-                           { t ( 'Click "Execute Preview" to see the live result' ) } 
390+                   </ CardHeader > 
391+                   < CardContent  className = "flex flex-1 flex-col" > 
392+                     < UrlParamsInput 
393+                       params = { previewParams } 
394+                       onChange = { setPreviewParams } 
395+                     /> 
396+ 
397+                     { previewKey  >  0  ? ( 
398+                       < div  className = "flex h-full flex-1 flex-col space-y-4" > 
399+                         < p  className = "text-muted-foreground text-sm" > 
400+                           { t ( 'Live preview of the worker API endpoint:' ) } 
396401                        </ p > 
397-                         { ! worker . active  &&  ( 
398-                           < p  className = "text-sm text-orange-500" > 
399-                             { t ( 'Worker must be active to preview' ) } 
402+                         < div  className = "relative h-full flex-1 rounded-md border bg-white" > 
403+                           { isLoadingPreview  &&  ( 
404+                             < div  className = "bg-background/80 absolute inset-0 z-10 flex items-center justify-center rounded-md backdrop-blur-sm" > 
405+                               < div  className = "flex items-center space-x-2" > 
406+                                 < div  className = "border-primary h-4 w-4 animate-spin rounded-full border-b-2"  /> 
407+                                 < span  className = "text-sm" > 
408+                                   { t ( 'Loading...' ) } 
409+                                 </ span > 
410+                               </ div > 
411+                             </ div > 
412+                           ) } 
413+                           < iframe 
414+                             key = { previewKey } 
415+                             src = { `${ window . location . origin } ${ workspaceId } ${ workerId } ${ getQueryString ( activePreviewParams )  ? `?${ getQueryString ( activePreviewParams ) }   : '' }  } 
416+                             className = "h-full w-full rounded-md" 
417+                             title = "Worker Preview" 
418+                             sandbox = "allow-same-origin allow-scripts" 
419+                             onLoad = { handlePreviewLoad } 
420+                           /> 
421+                         </ div > 
422+                       </ div > 
423+                     )  : ( 
424+                       < div  className = "text-muted-foreground flex h-[400px] items-center justify-center" > 
425+                         < div  className = "space-y-2 text-center" > 
426+                           < LuPlay  className = "mx-auto h-12 w-12"  /> 
427+                           < p > 
428+                             { t ( 
429+                               'Click "Execute Preview" to see the live result' 
430+                             ) } 
400431                          </ p > 
401-                         ) } 
432+                           { ! worker . active  &&  ( 
433+                             < p  className = "text-sm text-orange-500" > 
434+                               { t ( 'Worker must be active to preview' ) } 
435+                             </ p > 
436+                           ) } 
437+                         </ div > 
402438                      </ div > 
403-                     </ div > 
404-                   ) } 
405-                 </ CardContent > 
406-               </ Card > 
439+                     ) } 
440+                   </ CardContent > 
441+                 </ Card > 
442+               ) } 
407443            </ div > 
408444          </ TabsContent > 
409445
0 commit comments