@@ -2,7 +2,6 @@ import { conform, useForm } from "@conform-to/react";
22import { parse } from "@conform-to/zod" ;
33import { BeakerIcon , RectangleStackIcon } from "@heroicons/react/20/solid" ;
44import { ClockIcon } from "@heroicons/react/24/outline" ;
5- import { Form , useActionData , useFetcher } from "@remix-run/react" ;
65import { type ActionFunction , type LoaderFunctionArgs , json } from "@remix-run/server-runtime" ;
76import { useCallback , useEffect , useRef , useState , useMemo } from "react" ;
87import { typedjson , useTypedLoaderData } from "remix-typedjson" ;
@@ -14,7 +13,6 @@ import { Button } from "~/components/primitives/Buttons";
1413import { DateField } from "~/components/primitives/DateField" ;
1514import { Fieldset } from "~/components/primitives/Fieldset" ;
1615import { FormError } from "~/components/primitives/FormError" ;
17- import { Header2 } from "~/components/primitives/Headers" ;
1816import { Hint } from "~/components/primitives/Hint" ;
1917import { Input } from "~/components/primitives/Input" ;
2018import { InputGroup } from "~/components/primitives/InputGroup" ;
@@ -34,7 +32,7 @@ import { TextLink } from "~/components/primitives/TextLink";
3432import { TimezoneList } from "~/components/scheduled/timezones" ;
3533import { useEnvironment } from "~/hooks/useEnvironment" ;
3634import { useSearchParams } from "~/hooks/useSearchParam" ;
37- import { useParams } from "@remix-run/react" ;
35+ import { useParams , Form , useActionData , useFetcher } from "@remix-run/react" ;
3836import {
3937 redirectBackWithErrorMessage ,
4038 redirectWithErrorMessage ,
@@ -59,6 +57,7 @@ import { RunTagInput } from "~/components/runs/v3/RunTagInput";
5957import { type loader as queuesLoader } from "~/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues" ;
6058import { DateTime } from "~/components/primitives/DateTime" ;
6159import { TaskRunStatusCombo } from "~/components/runs/v3/TaskRunStatus" ;
60+
6261export const loader = async ( { request, params } : LoaderFunctionArgs ) => {
6362 const userId = await requireUserId ( request ) ;
6463 const { projectParam, organizationSlug, envParam, taskParam } = v3TaskParamsSchema . parse ( params ) ;
@@ -255,17 +254,11 @@ function StandardTaskForm({
255254 const { value, replace } = useSearchParams ( ) ;
256255 const tab = value ( "tab" ) ;
257256
258- //form submission
259257 const lastSubmission = useActionData ( ) ;
260-
261- //recent runs
262- const [ selectedCodeSampleId , setSelectedCodeSampleId ] = useState ( runs . at ( 0 ) ?. id ) ;
263- const selectedCodeSample = runs . find ( ( r ) => r . id === selectedCodeSampleId ) ;
264- const selectedCodeSamplePayload = selectedCodeSample ?. payload ;
265- const selectedCodeSampleMetadata = selectedCodeSample ?. seedMetadata ;
258+ const lastRun = runs [ 0 ] ;
266259
267260 const [ defaultPayloadJson , setDefaultPayloadJson ] = useState < string > (
268- selectedCodeSamplePayload ?? startingJson
261+ lastRun ?. payload ?? startingJson
269262 ) ;
270263 const setPayload = useCallback ( ( code : string ) => {
271264 setDefaultPayloadJson ( code ) ;
@@ -274,29 +267,27 @@ function StandardTaskForm({
274267 const currentPayloadJson = useRef < string > ( defaultPayloadJson ) ;
275268
276269 const [ defaultMetadataJson , setDefaultMetadataJson ] = useState < string > (
277- selectedCodeSampleMetadata ?? "{}"
270+ lastRun ?. seedMetadata ?? "{}"
278271 ) ;
279272 const setMetadata = useCallback ( ( code : string ) => {
280273 setDefaultMetadataJson ( code ) ;
281274 } , [ ] ) ;
282275
283276 const currentMetadataJson = useRef < string > ( defaultMetadataJson ) ;
284277
285- const [ ttlValue , setTtlValue ] = useState < number | undefined > ( selectedCodeSample ?. ttlSeconds ) ;
278+ const [ ttlValue , setTtlValue ] = useState < number | undefined > ( lastRun ?. ttlSeconds ) ;
286279 const [ concurrencyKeyValue , setConcurrencyKeyValue ] = useState < string | undefined > (
287- selectedCodeSample ?. concurrencyKey
288- ) ;
289- const [ queueValue , setQueueValue ] = useState < string | undefined > ( selectedCodeSample ?. queue ) ;
290- const [ machineValue , setMachineValue ] = useState < string | undefined > (
291- selectedCodeSample ?. machinePreset
280+ lastRun ?. concurrencyKey
292281 ) ;
282+ const [ queueValue , setQueueValue ] = useState < string | undefined > ( lastRun ?. queue ) ;
283+ const [ machineValue , setMachineValue ] = useState < string | undefined > ( lastRun ?. machinePreset ) ;
293284 const [ maxAttemptsValue , setMaxAttemptsValue ] = useState < number | undefined > (
294- selectedCodeSample ?. maxAttempts
285+ lastRun ?. maxAttempts
295286 ) ;
296287 const [ maxDurationValue , setMaxDurationValue ] = useState < number | undefined > (
297- selectedCodeSample ?. maxDurationInSeconds
288+ lastRun ?. maxDurationInSeconds
298289 ) ;
299- const [ tagsValue , setTagsValue ] = useState < string [ ] > ( selectedCodeSample ?. runTags ?? [ ] ) ;
290+ const [ tagsValue , setTagsValue ] = useState < string [ ] > ( lastRun ?. runTags ?? [ ] ) ;
300291
301292 const queueItems = queues . map ( ( q ) => ( {
302293 value : q . type === "task" ? `task/${ q . name } ` : q . name ,
@@ -376,7 +367,6 @@ function StandardTaskForm({
376367 onRunSelected = { ( run ) => {
377368 setPayload ( run . payload ) ;
378369 run . seedMetadata && setMetadata ( run . seedMetadata ) ;
379- setSelectedCodeSampleId ( run . id ) ;
380370 setTtlValue ( run . ttlSeconds ) ;
381371 setConcurrencyKeyValue ( run . concurrencyKey ) ;
382372 setMaxAttemptsValue ( run . maxAttempts ) ;
@@ -388,7 +378,7 @@ function StandardTaskForm({
388378 />
389379 </ div >
390380 </ TabContainer >
391- < ResizablePanelGroup orientation = "horizontal" >
381+ < ResizablePanelGroup orientation = "horizontal" className = "grow" >
392382 < ResizablePanel id = "test-task-main" min = "300px" >
393383 < div className = "flex h-full flex-col overflow-hidden bg-charcoal-900" >
394384 < div className = "flex-1 overflow-hidden" >
@@ -398,14 +388,7 @@ function StandardTaskForm({
398388 basicSetup
399389 onChange = { ( v ) => {
400390 currentPayloadJson . current = v ;
401-
402- //deselect the example if it's been edited
403- if ( selectedCodeSampleId ) {
404- if ( v !== selectedCodeSamplePayload ) {
405- setDefaultPayloadJson ( v ) ;
406- setSelectedCodeSampleId ( undefined ) ;
407- }
408- }
391+ setDefaultPayloadJson ( v ) ;
409392 } }
410393 height = "100%"
411394 autoFocus = { ! tab || tab === "payload" }
@@ -417,14 +400,7 @@ function StandardTaskForm({
417400 basicSetup
418401 onChange = { ( v ) => {
419402 currentMetadataJson . current = v ;
420-
421- //deselect the example if it's been edited
422- if ( selectedCodeSampleId ) {
423- if ( v !== selectedCodeSampleMetadata ) {
424- setDefaultMetadataJson ( v ) ;
425- setSelectedCodeSampleId ( undefined ) ;
426- }
427- }
403+ setDefaultMetadataJson ( v ) ;
428404 } }
429405 height = "100%"
430406 autoFocus = { tab === "metadata" }
@@ -670,25 +646,19 @@ function ScheduledTaskForm({
670646} ) {
671647 const environment = useEnvironment ( ) ;
672648 const lastSubmission = useActionData ( ) ;
673- const [ selectedCodeSampleId , setSelectedCodeSampleId ] = useState ( runs . at ( 0 ) ?. id ) ;
674- const [ timestampValue , setTimestampValue ] = useState < Date | undefined > ( ) ;
675- const [ lastTimestampValue , setLastTimestampValue ] = useState < Date | undefined > ( ) ;
676- const [ externalIdValue , setExternalIdValue ] = useState < string | undefined > ( ) ;
677- const [ timezoneValue , setTimezoneValue ] = useState < string > ( "UTC" ) ;
678649
679- //set initial values
680- useEffect ( ( ) => {
681- const initialRun = runs . find ( ( r ) => r . id === selectedCodeSampleId ) ;
682- if ( ! initialRun ) {
683- setTimestampValue ( new Date ( ) ) ;
684- return ;
685- }
650+ const lastRun = runs [ 0 ] ;
686651
687- setTimestampValue ( initialRun . payload . timestamp ) ;
688- setLastTimestampValue ( initialRun . payload . lastTimestamp ) ;
689- setExternalIdValue ( initialRun . payload . externalId ) ;
690- setTimezoneValue ( initialRun . payload . timezone ) ;
691- } , [ selectedCodeSampleId ] ) ;
652+ const [ timestampValue , setTimestampValue ] = useState < Date | undefined > (
653+ lastRun . payload . timestamp ?? new Date ( )
654+ ) ;
655+ const [ lastTimestampValue , setLastTimestampValue ] = useState < Date | undefined > (
656+ lastRun . payload . lastTimestamp
657+ ) ;
658+ const [ externalIdValue , setExternalIdValue ] = useState < string | undefined > (
659+ lastRun . payload . externalId
660+ ) ;
661+ const [ timezoneValue , setTimezoneValue ] = useState < string > ( lastRun . payload . timezone ?? "UTC" ) ;
692662
693663 const [
694664 form ,
@@ -711,7 +681,7 @@ function ScheduledTaskForm({
711681 } ) ;
712682
713683 return (
714- < Form className = "grid h-full max-h-full grid-rows-[1fr_auto] " method = "post" { ...form . props } >
684+ < Form className = "flex h-full max-h-full flex-col " method = "post" { ...form . props } >
715685 < input
716686 type = "hidden"
717687 { ...conform . input ( triggerSource , { type : "hidden" } ) }
@@ -727,7 +697,25 @@ function ScheduledTaskForm({
727697 { ...conform . input ( environmentId , { type : "hidden" } ) }
728698 value = { environment . id }
729699 />
730- < div className = "p-3" >
700+ < TabContainer className = "flex items-baseline justify-between pl-3 pr-2 pt-1.5" >
701+ < div className = "flex gap-5" >
702+ < TabButton isActive = { true } layoutId = "scheduled-task-options" >
703+ Options
704+ </ TabButton >
705+ </ div >
706+ < div className = "flex items-center gap-3" >
707+ < RecentRunsPopover
708+ runs = { runs }
709+ onRunSelected = { ( run ) => {
710+ setTimestampValue ( run . payload . timestamp ) ;
711+ setLastTimestampValue ( run . payload . lastTimestamp ) ;
712+ setExternalIdValue ( run . payload . externalId ) ;
713+ setTimezoneValue ( run . payload . timezone ) ;
714+ } }
715+ />
716+ </ div >
717+ </ TabContainer >
718+ < div className = "grow p-3" >
731719 < Fieldset >
732720 < InputGroup >
733721 < Label htmlFor = { timestamp . id } > Timestamp UTC</ Label >
0 commit comments