Skip to content

Commit 717fe3d

Browse files
feat(generator): Move Validate and Run in Cloud buttons to Header (#1112)
1 parent 2644b30 commit 717fe3d

6 files changed

Lines changed: 80 additions & 139 deletions

File tree

src/views/Generator/Generator.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,7 @@ export function Generator() {
154154
/>
155155
}
156156
actions={
157-
<GeneratorControls
158-
onSave={handleSaveGenerator}
159-
isDirty={isDirty}
160-
onChangeRecording={() => setSelectedRequest(null)}
161-
/>
157+
<GeneratorControls onSave={handleSaveGenerator} isDirty={isDirty} />
162158
}
163159
loading={isLoading}
164160
>
@@ -167,7 +163,6 @@ export function Generator() {
167163
<Allotment vertical>
168164
<Allotment.Pane minSize={200}>
169165
<GeneratorTabs
170-
fileName={fileName}
171166
selectedRequest={selectedRequest}
172167
onSelectRequest={setSelectedRequest}
173168
/>

src/views/Generator/GeneratorControls/GeneratorControls.tsx

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
import { DropdownMenu, Flex, IconButton } from '@radix-ui/themes'
2-
import { EllipsisVerticalIcon } from 'lucide-react'
1+
import { DropdownMenu, Flex, IconButton, Tooltip } from '@radix-ui/themes'
2+
import {
3+
CircleCheckBigIcon,
4+
DownloadIcon,
5+
EllipsisVerticalIcon,
6+
SaveIcon,
7+
} from 'lucide-react'
38
import { useState } from 'react'
49

510
import { ButtonWithTooltip } from '@/components/ButtonWithTooltip'
611
import { DeleteFileDialog } from '@/components/DeleteFileDialog'
12+
import { RunInCloudButton } from '@/components/RunInCloudDialog/RunInCloudButton'
13+
import { RunInCloudDialog } from '@/components/RunInCloudDialog/RunInCloudDialog'
714
import { useDeleteFile } from '@/hooks/useDeleteFile'
815
import { useProxyStatus } from '@/hooks/useProxyStatus'
916
import { useScriptPreview } from '@/hooks/useScriptPreview'
@@ -12,25 +19,20 @@ import { getFileNameWithoutExtension } from '@/utils/file'
1219

1320
import { ExportScriptDialog } from '../ExportScriptDialog'
1421
import { useGeneratorParams, useScriptExport } from '../Generator.hooks'
15-
import { RecordingSelector } from '../RecordingSelector'
1622
import { ValidatorDialog } from '../ValidatorDialog'
1723

1824
interface GeneratorControlsProps {
1925
onSave: () => void
2026
isDirty: boolean
21-
onChangeRecording: () => void
2227
}
2328

24-
export function GeneratorControls({
25-
onSave,
26-
isDirty,
27-
onChangeRecording,
28-
}: GeneratorControlsProps) {
29+
export function GeneratorControls({ onSave, isDirty }: GeneratorControlsProps) {
2930
const scriptName = useGeneratorStore((store) => store.scriptName)
3031

3132
const [isValidatorDialogOpen, setIsValidatorDialogOpen] = useState(false)
3233
const [isExportScriptDialogOpen, setIsExportScriptDialogOpen] =
3334
useState(false)
35+
const [isRunInCloudDialogOpen, setIsRunInCloudDialogOpen] = useState(false)
3436
const { fileName } = useGeneratorParams()
3537
const { preview, hasError } = useScriptPreview()
3638
const proxyStatus = useProxyStatus()
@@ -51,35 +53,59 @@ export function GeneratorControls({
5153

5254
return (
5355
<>
54-
<RecordingSelector onChangeRecording={onChangeRecording} />
5556
<Flex align="center" justify="between" gap="2" ml="2">
56-
<ButtonWithTooltip
57-
onClick={onSave}
58-
disabled={!isDirty}
59-
tooltip={!isDirty ? 'Changes saved' : ''}
60-
>
61-
Save generator
62-
</ButtonWithTooltip>
57+
<Flex gap="4" align="center">
58+
<Tooltip content={!isDirty ? 'Changes saved' : 'Save changes'}>
59+
<IconButton
60+
onClick={onSave}
61+
disabled={!isDirty}
62+
variant="ghost"
63+
color="gray"
64+
>
65+
<SaveIcon />
66+
</IconButton>
67+
</Tooltip>
68+
<Tooltip content="Export script">
69+
<IconButton
70+
onClick={() => setIsExportScriptDialogOpen(true)}
71+
disabled={!isScriptExportable}
72+
variant="ghost"
73+
color="gray"
74+
>
75+
<DownloadIcon />
76+
</IconButton>
77+
</Tooltip>
78+
</Flex>
79+
<Flex gap="4" align="center" pl="2">
80+
<ButtonWithTooltip
81+
variant="ghost"
82+
tooltip={
83+
!isScriptExportable
84+
? 'Fix script errors to enable validation'
85+
: proxyStatus !== 'online'
86+
? 'Start proxy to enable validation'
87+
: ''
88+
}
89+
onClick={() => setIsValidatorDialogOpen(true)}
90+
disabled={!isScriptExportable || proxyStatus !== 'online'}
91+
>
92+
<CircleCheckBigIcon /> Validate
93+
</ButtonWithTooltip>
94+
<RunInCloudButton
95+
variant="solid"
96+
disabled={!isScriptExportable}
97+
onClick={() => {
98+
setIsRunInCloudDialogOpen(true)
99+
}}
100+
/>
101+
</Flex>
63102
<DropdownMenu.Root>
64103
<DropdownMenu.Trigger>
65104
<IconButton variant="ghost" color="gray">
66105
<EllipsisVerticalIcon />
67106
</IconButton>
68107
</DropdownMenu.Trigger>
69108
<DropdownMenu.Content>
70-
<DropdownMenu.Item
71-
onSelect={() => setIsValidatorDialogOpen(true)}
72-
disabled={!isScriptExportable || proxyStatus !== 'online'}
73-
>
74-
Validate script
75-
</DropdownMenu.Item>
76-
<DropdownMenu.Item
77-
onSelect={() => setIsExportScriptDialogOpen(true)}
78-
disabled={!isScriptExportable}
79-
>
80-
Export script
81-
</DropdownMenu.Item>
82-
<DropdownMenu.Separator />
83109
<DeleteFileDialog
84110
file={file}
85111
onConfirm={handleDelete}
@@ -96,6 +122,11 @@ export function GeneratorControls({
96122
</DropdownMenu.Root>
97123
{isScriptExportable && (
98124
<>
125+
<RunInCloudDialog
126+
open={isRunInCloudDialogOpen}
127+
script={{ type: 'raw', name: fileName, content: preview }}
128+
onOpenChange={setIsRunInCloudDialogOpen}
129+
/>
99130
<ValidatorDialog
100131
script={preview}
101132
open={isValidatorDialogOpen}

src/views/Generator/GeneratorTabs/GeneratorTabs.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,11 @@ import { RequestList } from './RequestList'
1919
import { ScriptPreview } from './ScriptPreview'
2020

2121
interface GeneratorTabsProps {
22-
fileName: string
2322
selectedRequest: ProxyData | null
2423
onSelectRequest: (request: ProxyData | null) => void
2524
}
2625

2726
export function GeneratorTabs({
28-
fileName,
2927
selectedRequest,
3028
onSelectRequest,
3129
}: GeneratorTabsProps) {
@@ -94,7 +92,7 @@ export function GeneratorTabs({
9492
min-height: 0;
9593
`}
9694
>
97-
<ScriptPreview fileName={fileName} />
95+
<ScriptPreview />
9896
</Tabs.Content>
9997
</Tabs.Root>
10098
</Flex>

src/views/Generator/GeneratorTabs/RequestList/Header.tsx

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
import { Flex, Switch, Text } from '@radix-ui/themes'
22

33
import { Filter } from '@/components/WebLogView/Filter'
4-
import { RecorderIcon } from '@/components/icons'
54
import { useGeneratorStore } from '@/store/generator'
6-
import { getFileNameWithoutExtension } from '@/utils/file'
5+
6+
import { RecordingSelector } from '../../RecordingSelector'
7+
8+
interface HeaderProps {
9+
filter: string
10+
filterAllData?: boolean
11+
onChangeRecording: () => void
12+
setFilter: (filter: string) => void
13+
setFilterAllData: (filterAllData: boolean) => void
14+
}
715

816
export function Header({
917
filter,
1018
setFilter,
1119
filterAllData,
1220
setFilterAllData,
13-
}: {
14-
filter: string
15-
setFilter: (filter: string) => void
16-
filterAllData?: boolean
17-
setFilterAllData: (filterAllData: boolean) => void
18-
}) {
21+
onChangeRecording,
22+
}: HeaderProps) {
1923
const previewOriginalRequests = useGeneratorStore(
2024
(state) => state.previewOriginalRequests
2125
)
@@ -24,18 +28,9 @@ export function Header({
2428
(store) => store.setPreviewOriginalRequests
2529
)
2630

27-
const recordingPath = useGeneratorStore((state) => state.recordingPath)
28-
2931
return (
3032
<Flex justify="between" align="center" px="2" py="1" gap="2">
31-
<Text color="gray" size="2" truncate>
32-
<Flex align="center" gap="1">
33-
<Flex flexShrink="0">
34-
<RecorderIcon width="22px" />
35-
</Flex>
36-
<Text truncate>{getFileNameWithoutExtension(recordingPath)}</Text>
37-
</Flex>
38-
</Text>
33+
<RecordingSelector onChangeRecording={onChangeRecording} />
3934
<Flex justify="end" align="center" gap="4">
4035
<Text
4136
as="label"

src/views/Generator/GeneratorTabs/RequestList/RequestList.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ export function RequestList({
7171
{!recordingError && (
7272
<Header
7373
filter={filter}
74-
setFilter={setFilter}
7574
filterAllData={filterAllData}
75+
onChangeRecording={() => onSelectRequest(null)}
76+
setFilter={setFilter}
7677
setFilterAllData={setFilterAllData}
7778
/>
7879
)}
Lines changed: 2 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,17 @@
1-
import { Flex, Tooltip } from '@radix-ui/themes'
2-
import { CircleCheckIcon, DownloadIcon } from 'lucide-react'
3-
import { useState } from 'react'
1+
import { Flex } from '@radix-ui/themes'
42

5-
import { GhostButton } from '@/components/GhostButton'
63
import { ReactMonacoEditor } from '@/components/Monaco/ReactMonacoEditor'
7-
import { RunInCloudButton } from '@/components/RunInCloudDialog/RunInCloudButton'
8-
import { RunInCloudDialog } from '@/components/RunInCloudDialog/RunInCloudDialog'
9-
import { useProxyStatus } from '@/hooks/useProxyStatus'
104
import { useScriptPreview } from '@/hooks/useScriptPreview'
115
import { useTrackScriptCopy } from '@/hooks/useTrackScriptCopy'
12-
import { useGeneratorStore } from '@/store/generator'
13-
14-
import { ExportScriptDialog } from '../ExportScriptDialog'
15-
import { useScriptExport } from '../Generator.hooks'
16-
import { ValidatorDialog } from '../ValidatorDialog'
176

187
import { ScriptPreviewError } from './ScriptPreviewError'
198

20-
interface ScriptPreviewProps {
21-
fileName: string
22-
}
23-
24-
export function ScriptPreview({ fileName }: ScriptPreviewProps) {
25-
const scriptName = useGeneratorStore((store) => store.scriptName)
26-
27-
const [isRunInCloudDialogOpen, setIsRunInCloudDialogOpen] = useState(false)
28-
const [isValidatorDialogOpen, setIsValidatorDialogOpen] = useState(false)
29-
const [isExportScriptDialogOpen, setIsExportScriptDialogOpen] =
30-
useState(false)
9+
export function ScriptPreview() {
3110
const { preview, error } = useScriptPreview()
32-
const proxyStatus = useProxyStatus()
33-
34-
const isScriptExportable = !error && !!preview
35-
36-
const handleExportScript = useScriptExport(fileName)
3711
const handleCopy = useTrackScriptCopy(preview, 'generator')
3812

3913
return (
4014
<Flex direction="column" height="100%" position="relative">
41-
<Flex py="1" px="2" gap="2" align="center" justify="end">
42-
<Tooltip
43-
content={`Proxy is ${proxyStatus}`}
44-
hidden={proxyStatus === 'online'}
45-
>
46-
<GhostButton
47-
disabled={!isScriptExportable || proxyStatus !== 'online'}
48-
onClick={() => {
49-
setIsValidatorDialogOpen(true)
50-
}}
51-
>
52-
<CircleCheckIcon />
53-
Validate
54-
</GhostButton>
55-
</Tooltip>
56-
<GhostButton
57-
disabled={!isScriptExportable}
58-
onClick={() => {
59-
setIsExportScriptDialogOpen(true)
60-
}}
61-
>
62-
<DownloadIcon />
63-
Export
64-
</GhostButton>
65-
<RunInCloudButton
66-
variant="outline"
67-
disabled={!isScriptExportable}
68-
onClick={() => {
69-
setIsRunInCloudDialogOpen(true)
70-
}}
71-
/>
72-
</Flex>
7315
<ReactMonacoEditor
7416
showToolbar
7517
defaultLanguage="javascript"
@@ -81,27 +23,6 @@ export function ScriptPreview({ fileName }: ScriptPreviewProps) {
8123
/>
8224

8325
{!!error && <ScriptPreviewError error={error} />}
84-
85-
{isScriptExportable && (
86-
<>
87-
<RunInCloudDialog
88-
open={isRunInCloudDialogOpen}
89-
script={{ type: 'raw', name: fileName, content: preview }}
90-
onOpenChange={setIsRunInCloudDialogOpen}
91-
/>
92-
<ValidatorDialog
93-
script={preview}
94-
open={isValidatorDialogOpen}
95-
onOpenChange={setIsValidatorDialogOpen}
96-
/>
97-
<ExportScriptDialog
98-
open={isExportScriptDialogOpen}
99-
scriptName={scriptName}
100-
onExport={handleExportScript}
101-
onOpenChange={setIsExportScriptDialogOpen}
102-
/>
103-
</>
104-
)}
10526
</Flex>
10627
)
10728
}

0 commit comments

Comments
 (0)