55 ChatBubbleLeftEllipsisIcon ,
66 PauseIcon ,
77 PlayIcon ,
8+ PlusIcon ,
89 RectangleStackIcon ,
10+ XMarkIcon ,
911} from "@heroicons/react/20/solid" ;
1012import { DialogClose } from "@radix-ui/react-dialog" ;
1113import { Form , useNavigation , useSearchParams , type MetaFunction } from "@remix-run/react" ;
@@ -28,9 +30,12 @@ import { Badge } from "~/components/primitives/Badge";
2830import { Button , LinkButton , type ButtonVariant } from "~/components/primitives/Buttons" ;
2931import { Callout } from "~/components/primitives/Callout" ;
3032import { Dialog , DialogContent , DialogHeader , DialogTrigger } from "~/components/primitives/Dialog" ;
33+ import { Fieldset } from "~/components/primitives/Fieldset" ;
3134import { FormButtons } from "~/components/primitives/FormButtons" ;
3235import { Header3 } from "~/components/primitives/Headers" ;
3336import { Input } from "~/components/primitives/Input" ;
37+ import { InputGroup } from "~/components/primitives/InputGroup" ;
38+ import { Label } from "~/components/primitives/Label" ;
3439import { SearchInput } from "~/components/primitives/SearchInput" ;
3540import { NavBar , PageAccessories , PageTitle } from "~/components/primitives/PageHeader" ;
3641import { PaginationControls } from "~/components/primitives/Pagination" ;
@@ -944,7 +949,7 @@ function QueueOverrideLimitsButton({
944949 queue . concurrencyLimit ?. toString ( ) ?? environmentConcurrencyLimit . toString ( )
945950 ) ;
946951 const [ rateLimits , setRateLimits ] = useState < Array < { limit : number ; window : number } > > (
947- queue . rateLimit ?? [ ]
952+ queue . rateLimit && queue . rateLimit . length > 0 ? queue . rateLimit : [ { limit : 0 , window : 0 } ]
948953 ) ;
949954
950955 const isOverridden = ! ! queue . concurrency ?. overriddenAt || ( queue . rateLimit && queue . rateLimit . length > 0 ) ;
@@ -969,35 +974,35 @@ function QueueOverrideLimitsButton({
969974 title = { isOverridden ? "Edit override…" : "Override limit…" }
970975 />
971976 </ DialogTrigger >
972- < DialogContent >
973- < DialogHeader >
977+ < DialogContent className = "p-0 pt-2.5 md:max-w-lg" >
978+ < DialogHeader className = "px-4" >
974979 { isOverridden ? "Edit limits override" : "Override limits" }
975980 </ DialogHeader >
976- < div className = "flex flex-col gap-3 pt-3" >
977- { isOverridden ? (
978- < Paragraph >
979- This queue's limits are currently overridden.
980- { typeof queue . concurrency ?. base === "number" &&
981- ` The original concurrency limit set in code was ${ queue . concurrency . base } .` } { " " }
982- You can update the override or remove it to restore the { " " }
983- { typeof queue . concurrency ?. base === "number"
984- ? "limit set in code"
985- : "environment concurrency limit"}
986- .
987- </ Paragraph >
988- ) : (
989- < Paragraph >
990- Override this queue's limits. The current concurrency limit is { currentLimit } , which is
991- set { queue . concurrencyLimit !== null ? "in code" : "by the environment" } .
992- </ Paragraph >
993- ) }
994- < Form method = "post" onSubmit = { ( ) => setIsOpen ( false ) } className = "space-y-3" >
995- < input type = "hidden" name = "friendlyId" value = { queue . id } />
996- < input type = "hidden" name = "rateLimits" value = { JSON . stringify ( rateLimits ) } / >
997- < div className = "space-y-2" >
998- < label htmlFor = "concurrencyLimit" className = "text-sm text-text-bright" >
999- Concurrency limit
1000- </ label >
981+ < Form method = "post" onSubmit = { ( ) => setIsOpen ( false ) } >
982+ < input type = "hidden" name = "friendlyId" value = { queue . id } />
983+ < input type = "hidden" name = "rateLimits" value = { JSON . stringify ( rateLimits . filter ( rl => rl . limit > 0 && rl . window > 0 ) ) } / >
984+
985+ < Fieldset className = "max-h-[70vh] overflow-y-auto p-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 space-y-4" >
986+ { isOverridden ? (
987+ < Paragraph >
988+ This queue's limits are currently overridden.
989+ { typeof queue . concurrency ?. base === "number" &&
990+ ` The original concurrency limit set in code was ${ queue . concurrency . base } .` } { " "}
991+ You can update the override or remove it to restore the { " " }
992+ { typeof queue . concurrency ?. base === "number"
993+ ? "limit set in code"
994+ : "environment concurrency limit" }
995+ .
996+ </ Paragraph >
997+ ) : (
998+ < Paragraph >
999+ Override this queue's limits. The current concurrency limit is { currentLimit } , which is
1000+ set { queue . concurrencyLimit !== null ? "in code" : "by the environment" } .
1001+ </ Paragraph >
1002+ ) }
1003+
1004+ < InputGroup fullWidth >
1005+ < Label htmlFor = "concurrencyLimit" > Concurrency limit </ Label >
10011006 < Input
10021007 type = "number"
10031008 name = "concurrencyLimit"
@@ -1009,100 +1014,114 @@ function QueueOverrideLimitsButton({
10091014 placeholder = { currentLimit . toString ( ) }
10101015 autoFocus
10111016 />
1012- </ div >
1017+ </ InputGroup >
10131018
1014- < div className = "space-y-2" >
1015- < label className = "text-sm text-text-bright" > Rate limits</ label >
1019+ < InputGroup fullWidth >
1020+ < div className = "grid w-full grid-cols-[1fr_1fr] gap-1.5" >
1021+ < Label > Rate limit</ Label >
1022+ < Label > Window (seconds)</ Label >
1023+ </ div >
10161024 { rateLimits . map ( ( rl , index ) => (
1017- < div key = { index } className = "flex items-center gap-2" >
1018- < Input
1019- type = "number"
1020- min = "1"
1021- value = { rl . limit }
1022- onChange = { ( e ) => {
1023- const newLimits = [ ...rateLimits ] ;
1024- newLimits [ index ] . limit = parseInt ( e . target . value , 10 ) ;
1025- setRateLimits ( newLimits ) ;
1026- } }
1027- placeholder = "Limit"
1028- />
1029- < span className = "text-text-dimmed" > per</ span >
1025+ < div key = { index } className = "grid w-full grid-cols-[1fr_1fr] gap-1.5" >
10301026 < Input
10311027 type = "number"
10321028 min = "1"
1033- value = { rl . window }
1029+ value = { rl . limit || "" }
10341030 onChange = { ( e ) => {
10351031 const newLimits = [ ...rateLimits ] ;
1036- newLimits [ index ] . window = parseInt ( e . target . value , 10 ) ;
1032+ newLimits [ index ] . limit = parseInt ( e . target . value , 10 ) || 0 ;
10371033 setRateLimits ( newLimits ) ;
10381034 } }
1039- placeholder = "Window (s) "
1035+ placeholder = "e.g. 10 "
10401036 />
1041- < span className = "text-text-dimmed" > seconds</ span >
1042- < Button
1043- type = "button"
1044- variant = "tertiary/small"
1045- onClick = { ( ) => {
1046- const newLimits = [ ...rateLimits ] ;
1047- newLimits . splice ( index , 1 ) ;
1048- setRateLimits ( newLimits ) ;
1049- } }
1050- >
1051- Remove
1052- </ Button >
1037+ < div className = "flex items-start gap-1" >
1038+ < div className = "grow" >
1039+ < Input
1040+ type = "number"
1041+ min = "1"
1042+ value = { rl . window || "" }
1043+ onChange = { ( e ) => {
1044+ const newLimits = [ ...rateLimits ] ;
1045+ newLimits [ index ] . window = parseInt ( e . target . value , 10 ) || 0 ;
1046+ setRateLimits ( newLimits ) ;
1047+ } }
1048+ placeholder = "e.g. 60"
1049+ />
1050+ </ div >
1051+ { rateLimits . length > 1 && (
1052+ < Button
1053+ type = "button"
1054+ variant = "minimal/medium"
1055+ onClick = { ( ) => {
1056+ const newLimits = [ ...rateLimits ] ;
1057+ newLimits . splice ( index , 1 ) ;
1058+ setRateLimits ( newLimits ) ;
1059+ } }
1060+ LeadingIcon = { XMarkIcon }
1061+ />
1062+ ) }
1063+ </ div >
10531064 </ div >
10541065 ) ) }
1055- < Button
1056- type = "button"
1057- variant = "secondary/small"
1058- onClick = { ( ) => setRateLimits ( [ ...rateLimits , { limit : 10 , window : 60 } ] ) }
1059- >
1060- Add rate limit
1061- </ Button >
1062- </ div >
1063-
1064- < FormButtons
1065- defaultAction = { {
1066- name : "action" ,
1067- value : "queue-override" ,
1068- disabled : isLoading || ! concurrencyLimit ,
1069- } }
1070- confirmButton = {
1066+ < div className = "flex items-center justify-between gap-4" >
1067+ < Paragraph variant = "extra-small" >
1068+ Tip: You can also set dynamic rate limits in your code.
1069+ </ Paragraph >
10711070 < Button
1072- type = "submit"
1073- name = "action"
1074- value = "queue-override"
1075- disabled = { isLoading || ! concurrencyLimit }
1076- variant = "primary/medium"
1077- LeadingIcon = { isLoading && < Spinner color = "white" /> }
1078- shortcut = { { modifiers : [ "mod" ] , key : "enter" } }
1071+ type = "button"
1072+ variant = "tertiary/medium"
1073+ className = "w-fit"
1074+ onClick = { ( ) => setRateLimits ( [ ...rateLimits , { limit : 0 , window : 0 } ] ) }
1075+ LeadingIcon = { PlusIcon }
10791076 >
1080- { isOverridden ? "Update override" : "Override limit" }
1077+ Add another
10811078 </ Button >
1082- }
1083- cancelButton = {
1084- < div className = "flex items-center justify-between gap-2" >
1085- { isOverridden && (
1086- < Button
1087- type = "submit"
1088- name = "action"
1089- value = "queue-remove-override"
1090- disabled = { isLoading }
1091- variant = "danger/medium"
1092- >
1093- Remove override
1094- </ Button >
1095- ) }
1096- < DialogClose asChild >
1097- < Button type = "button" variant = "tertiary/medium" >
1098- Cancel
1099- </ Button >
1100- </ DialogClose >
1101- </ div >
1102- }
1103- />
1104- </ Form >
1105- </ div >
1079+ </ div >
1080+ </ InputGroup >
1081+ </ Fieldset >
1082+
1083+ < FormButtons
1084+ className = "px-4 pb-4"
1085+ defaultAction = { {
1086+ name : "action" ,
1087+ value : "queue-override" ,
1088+ disabled : isLoading || ! concurrencyLimit ,
1089+ } }
1090+ confirmButton = {
1091+ < Button
1092+ type = "submit"
1093+ name = "action"
1094+ value = "queue-override"
1095+ disabled = { isLoading || ! concurrencyLimit }
1096+ variant = "primary/medium"
1097+ LeadingIcon = { isLoading && < Spinner color = "white" /> }
1098+ shortcut = { { modifiers : [ "mod" ] , key : "enter" } }
1099+ >
1100+ { isOverridden ? "Update override" : "Override limit" }
1101+ </ Button >
1102+ }
1103+ cancelButton = {
1104+ < div className = "flex items-center justify-between gap-2" >
1105+ { isOverridden && (
1106+ < Button
1107+ type = "submit"
1108+ name = "action"
1109+ value = "queue-remove-override"
1110+ disabled = { isLoading }
1111+ variant = "danger/medium"
1112+ >
1113+ Remove override
1114+ </ Button >
1115+ ) }
1116+ < DialogClose asChild >
1117+ < Button type = "button" variant = "tertiary/medium" >
1118+ Cancel
1119+ </ Button >
1120+ </ DialogClose >
1121+ </ div >
1122+ }
1123+ />
1124+ </ Form >
11061125 </ DialogContent >
11071126 </ Dialog >
11081127 ) ;
0 commit comments