Skip to content

Commit 67ae4f0

Browse files
committed
feat: add preview collapse button in worker page
1 parent 6f18466 commit 67ae4f0

File tree

1 file changed

+117
-81
lines changed

1 file changed

+117
-81
lines changed

src/client/routes/worker/$workerId/index.tsx

Lines changed: 117 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import {
2020
PaginationPrevious,
2121
} from '@/components/ui/pagination';
2222
import { CodeEditor } from '@/components/CodeEditor';
23-
2423
import { trpc } from '@/api/trpc';
24+
import { cn } from '@/utils/style';
2525
import { defaultErrorHandler } from '@/api/trpc';
2626
import {
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';
3639
import { AlertConfirm } from '@/components/AlertConfirm';
3740
import { Loading } from '@/components/Loading';
3841
import { 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}/api/worker/${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}/api/worker/${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

Comments
 (0)