@@ -27,9 +27,11 @@ import {
2727 ResizablePanelGroup ,
2828} from "~/components/primitives/Resizable" ;
2929import { Select } from "~/components/primitives/Select" ;
30+ import { TabButton , TabContainer } from "~/components/primitives/Tabs" ;
3031import { TextLink } from "~/components/primitives/TextLink" ;
3132import { TaskRunStatusCombo } from "~/components/runs/v3/TaskRunStatus" ;
3233import { TimezoneList } from "~/components/scheduled/timezones" ;
34+ import { useSearchParams } from "~/hooks/useSearchParam" ;
3335import { redirectBackWithErrorMessage , redirectWithSuccessMessage } from "~/models/message.server" ;
3436import {
3537 ScheduledRun ,
@@ -39,6 +41,7 @@ import {
3941} from "~/presenters/v3/TestTaskPresenter.server" ;
4042import { logger } from "~/services/logger.server" ;
4143import { requireUserId } from "~/services/session.server" ;
44+ import { cn } from "~/utils/cn" ;
4245import { docsPath , v3RunSpanPath , v3TaskParamsSchema } from "~/utils/pathBuilder" ;
4346import { TestTaskService } from "~/v3/services/testTask.server" ;
4447import { OutOfEntitlementError } from "~/v3/services/triggerTask.server" ;
@@ -129,27 +132,44 @@ export default function Page() {
129132const startingJson = "{\n\n}" ;
130133
131134function StandardTaskForm ( { task, runs } : { task : TestTask [ "task" ] ; runs : StandardRun [ ] } ) {
135+ const { value, replace } = useSearchParams ( ) ;
136+ const tab = value ( "tab" ) ;
137+
132138 //form submission
133139 const submit = useSubmit ( ) ;
134140 const lastSubmission = useActionData ( ) ;
135141
136142 //recent runs
137143 const [ selectedCodeSampleId , setSelectedCodeSampleId ] = useState ( runs . at ( 0 ) ?. id ) ;
138- const selectedCodeSample = runs . find ( ( r ) => r . id === selectedCodeSampleId ) ?. payload ;
144+ const selectedCodeSample = runs . find ( ( r ) => r . id === selectedCodeSampleId ) ;
145+ const selectedCodeSamplePayload = selectedCodeSample ?. payload ;
146+ const selectedCodeSampleMetadata = selectedCodeSample ?. metadata ;
139147
140- const [ defaultJson , setDefaultJson ] = useState < string > ( selectedCodeSample ?? startingJson ) ;
141- const setCode = useCallback ( ( code : string ) => {
142- setDefaultJson ( code ) ;
148+ const [ defaultPayloadJson , setDefaultPayloadJson ] = useState < string > (
149+ selectedCodeSamplePayload ?? startingJson
150+ ) ;
151+ const setPayload = useCallback ( ( code : string ) => {
152+ setDefaultPayloadJson ( code ) ;
143153 } , [ ] ) ;
144154
145- const currentJson = useRef < string > ( defaultJson ) ;
155+ const currentPayloadJson = useRef < string > ( defaultPayloadJson ) ;
156+
157+ const [ defaultMetadataJson , setDefaultMetadataJson ] = useState < string > (
158+ selectedCodeSampleMetadata ?? "{}"
159+ ) ;
160+ const setMetadata = useCallback ( ( code : string ) => {
161+ setDefaultMetadataJson ( code ) ;
162+ } , [ ] ) ;
163+
164+ const currentMetadataJson = useRef < string > ( defaultMetadataJson ) ;
146165
147166 const submitForm = useCallback (
148167 ( e : React . FormEvent < HTMLFormElement > ) => {
149168 submit (
150169 {
151170 triggerSource : "STANDARD" ,
152- payload : currentJson . current ,
171+ payload : currentPayloadJson . current ,
172+ metadata : currentMetadataJson . current ,
153173 taskIdentifier : task . taskIdentifier ,
154174 environmentId : task . environment . id ,
155175 } ,
@@ -160,7 +180,7 @@ function StandardTaskForm({ task, runs }: { task: TestTask["task"]; runs: Standa
160180 ) ;
161181 e . preventDefault ( ) ;
162182 } ,
163- [ currentJson ]
183+ [ currentPayloadJson , currentMetadataJson ]
164184 ) ;
165185
166186 const [ form , { environmentId, payload } ] = useForm ( {
@@ -183,28 +203,73 @@ function StandardTaskForm({ task, runs }: { task: TestTask["task"]; runs: Standa
183203 < ResizablePanelGroup orientation = "horizontal" >
184204 < ResizablePanel id = "test-task-main" min = "100px" default = "60%" >
185205 < div className = "h-full bg-charcoal-900" >
186- < JSONEditor
187- defaultValue = { defaultJson }
188- readOnly = { false }
189- basicSetup
190- onChange = { ( v ) => {
191- currentJson . current = v ;
192-
193- //deselect the example if it's been edited
194- if ( selectedCodeSampleId ) {
195- if ( v !== selectedCodeSample ) {
196- setDefaultJson ( v ) ;
197- setSelectedCodeSampleId ( undefined ) ;
206+ < TabContainer className = "px-3 pt-2" >
207+ < TabButton
208+ isActive = { ! tab || tab === "payload" }
209+ layoutId = "test-editor"
210+ onClick = { ( ) => {
211+ replace ( { tab : "payload" } ) ;
212+ } }
213+ >
214+ Payload
215+ </ TabButton >
216+
217+ < TabButton
218+ isActive = { tab === "metadata" }
219+ layoutId = "test-editor"
220+ onClick = { ( ) => {
221+ replace ( { tab : "metadata" } ) ;
222+ } }
223+ >
224+ Metadata
225+ </ TabButton >
226+ </ TabContainer >
227+ < div >
228+ < JSONEditor
229+ defaultValue = { defaultPayloadJson }
230+ readOnly = { false }
231+ basicSetup
232+ onChange = { ( v ) => {
233+ currentPayloadJson . current = v ;
234+
235+ //deselect the example if it's been edited
236+ if ( selectedCodeSampleId ) {
237+ if ( v !== selectedCodeSamplePayload ) {
238+ setDefaultPayloadJson ( v ) ;
239+ setSelectedCodeSampleId ( undefined ) ;
240+ }
198241 }
199- }
200- } }
201- height = "100%"
202- min-height = "100%"
203- max-height = "100%"
204- autoFocus
205- placeholder = "Use your schema to enter valid JSON or add one of the recent payloads then click 'Run test'"
206- className = "h-full"
207- />
242+ } }
243+ height = "100%"
244+ min-height = "100%"
245+ max-height = "100%"
246+ autoFocus
247+ placeholder = "{ }"
248+ className = { cn ( "h-full" , tab === "metadata" && "hidden" ) }
249+ />
250+ < JSONEditor
251+ defaultValue = { defaultMetadataJson }
252+ readOnly = { false }
253+ basicSetup
254+ onChange = { ( v ) => {
255+ currentMetadataJson . current = v ;
256+
257+ //deselect the example if it's been edited
258+ if ( selectedCodeSampleId ) {
259+ if ( v !== selectedCodeSampleMetadata ) {
260+ setDefaultMetadataJson ( v ) ;
261+ setSelectedCodeSampleId ( undefined ) ;
262+ }
263+ }
264+ } }
265+ height = "100%"
266+ min-height = "100%"
267+ max-height = "100%"
268+ autoFocus
269+ placeholder = ""
270+ className = { cn ( "h-full" , tab !== "metadata" && "hidden" ) }
271+ />
272+ </ div >
208273 </ div >
209274 </ ResizablePanel >
210275 < ResizableHandle id = "test-task-handle" />
@@ -213,9 +278,10 @@ function StandardTaskForm({ task, runs }: { task: TestTask["task"]; runs: Standa
213278 runs = { runs }
214279 selectedId = { selectedCodeSampleId }
215280 onSelected = { ( id ) => {
216- const payload = runs . find ( ( r ) => r . id === id ) ?. payload ;
217- if ( ! payload ) return ;
218- setCode ( payload ) ;
281+ const run = runs . find ( ( r ) => r . id === id ) ;
282+ if ( ! run ) return ;
283+ setPayload ( run . payload ) ;
284+ run . metadata && setMetadata ( run . metadata ) ;
219285 setSelectedCodeSampleId ( id ) ;
220286 } }
221287 />
0 commit comments