1- import { TaskQueueType } from "@trigger.dev/database" ;
1+ import type { RunEngine } from "@internal/run-engine" ;
2+ import { Prisma , TaskQueueType } from "@trigger.dev/database" ;
3+ import { type PrismaClientOrTransaction } from "~/db.server" ;
24import { type AuthenticatedEnvironment } from "~/services/apiAuth.server" ;
35import { determineEngineVersion } from "~/v3/engineVersion.server" ;
46import { engine } from "~/v3/runEngine.server" ;
57import { BasePresenter } from "./basePresenter.server" ;
68import { toQueueItem } from "./QueueRetrievePresenter.server" ;
79
10+ type QueueListEngine = Pick < RunEngine , "lengthOfQueues" | "currentConcurrencyOfQueues" > ;
11+
812const DEFAULT_ITEMS_PER_PAGE = 25 ;
913const MAX_ITEMS_PER_PAGE = 100 ;
1014
@@ -13,12 +17,54 @@ const typeToDBQueueType: Record<"task" | "custom", TaskQueueType> = {
1317 custom : TaskQueueType . NAMED ,
1418} ;
1519
20+ export type QueueListFilteredPagination = {
21+ mode : "filtered" ;
22+ currentPage : number ;
23+ hasMore : boolean ;
24+ } ;
25+
26+ export type QueueListUnfilteredPagination = {
27+ mode : "unfiltered" ;
28+ currentPage : number ;
29+ totalPages : number ;
30+ count : number ;
31+ } ;
32+
33+ export type QueueListPagination = QueueListFilteredPagination | QueueListUnfilteredPagination ;
34+
35+ function buildQueueListWhere (
36+ environmentId : string ,
37+ query : string | undefined ,
38+ type : "task" | "custom" | undefined
39+ ) : Prisma . TaskQueueWhereInput {
40+ const trimmedQuery = query ?. trim ( ) ;
41+
42+ return {
43+ runtimeEnvironmentId : environmentId ,
44+ version : "V2" ,
45+ name : trimmedQuery
46+ ? {
47+ contains : trimmedQuery ,
48+ mode : "insensitive" ,
49+ }
50+ : undefined ,
51+ type : type ? typeToDBQueueType [ type ] : undefined ,
52+ } ;
53+ }
54+
1655export class QueueListPresenter extends BasePresenter {
1756 private readonly perPage : number ;
57+ private readonly engineClient : QueueListEngine ;
1858
19- constructor ( perPage : number = DEFAULT_ITEMS_PER_PAGE ) {
20- super ( ) ;
59+ constructor (
60+ perPage : number = DEFAULT_ITEMS_PER_PAGE ,
61+ prismaClient ?: PrismaClientOrTransaction ,
62+ replicaClient ?: PrismaClientOrTransaction ,
63+ engineClient : QueueListEngine = engine
64+ ) {
65+ super ( prismaClient , replicaClient ) ;
2166 this . perPage = Math . min ( perPage , MAX_ITEMS_PER_PAGE ) ;
67+ this . engineClient = engineClient ;
2268 }
2369
2470 public async call ( {
@@ -33,26 +79,14 @@ export class QueueListPresenter extends BasePresenter {
3379 perPage ?: number ;
3480 type ?: "task" | "custom" ;
3581 } ) {
36- const hasFilters = ( query !== undefined && query . length > 0 ) || type !== undefined ;
82+ const hasFilters = Boolean ( query ?. trim ( ) ) || type !== undefined ;
3783
38- // Get total count for pagination
39- const totalQueues = await this . _replica . taskQueue . count ( {
40- where : {
41- runtimeEnvironmentId : environment . id ,
42- version : "V2" ,
43- name : query
44- ? {
45- contains : query ,
46- mode : "insensitive" ,
47- }
48- : undefined ,
49- type : type ? typeToDBQueueType [ type ] : undefined ,
50- } ,
51- } ) ;
52-
53- //check the engine is the correct version
5484 const engineVersion = await determineEngineVersion ( { environment } ) ;
5585 if ( engineVersion === "V1" ) {
86+ const totalQueues = await this . _replica . taskQueue . count ( {
87+ where : buildQueueListWhere ( environment . id , query , type ) ,
88+ } ) ;
89+
5690 if ( totalQueues === 0 ) {
5791 const oldQueue = await this . _replica . taskQueue . findFirst ( {
5892 where : {
@@ -78,10 +112,30 @@ export class QueueListPresenter extends BasePresenter {
78112 } ;
79113 }
80114
115+ if ( hasFilters ) {
116+ const { queues, hasMore } = await this . getFilteredQueues ( environment , query , page , type ) ;
117+
118+ return {
119+ success : true as const ,
120+ queues,
121+ pagination : {
122+ mode : "filtered" as const ,
123+ currentPage : page ,
124+ hasMore,
125+ } ,
126+ hasFilters,
127+ } ;
128+ }
129+
130+ const totalQueues = await this . _replica . taskQueue . count ( {
131+ where : buildQueueListWhere ( environment . id , query , type ) ,
132+ } ) ;
133+
81134 return {
82135 success : true as const ,
83- queues : await this . getQueuesWithPagination ( environment , query , page , type ) ,
136+ queues : await this . getUnfilteredQueues ( environment , page , type ) ,
84137 pagination : {
138+ mode : "unfiltered" as const ,
85139 currentPage : page ,
86140 totalPages : Math . ceil ( totalQueues / this . perPage ) ,
87141 count : totalQueues ,
@@ -91,24 +145,47 @@ export class QueueListPresenter extends BasePresenter {
91145 } ;
92146 }
93147
94- private async getQueuesWithPagination (
148+ private async getFilteredQueues (
95149 environment : AuthenticatedEnvironment ,
96150 query : string | undefined ,
97151 page : number ,
98152 type : "task" | "custom" | undefined
99153 ) {
100154 const queues = await this . _replica . taskQueue . findMany ( {
101- where : {
102- runtimeEnvironmentId : environment . id ,
103- version : "V2" ,
104- name : query
105- ? {
106- contains : query ,
107- mode : "insensitive" ,
108- }
109- : undefined ,
110- type : type ? typeToDBQueueType [ type ] : undefined ,
155+ where : buildQueueListWhere ( environment . id , query , type ) ,
156+ select : {
157+ friendlyId : true ,
158+ name : true ,
159+ orderableName : true ,
160+ concurrencyLimit : true ,
161+ concurrencyLimitBase : true ,
162+ concurrencyLimitOverriddenAt : true ,
163+ concurrencyLimitOverriddenBy : true ,
164+ type : true ,
165+ paused : true ,
166+ } ,
167+ orderBy : {
168+ orderableName : "asc" ,
111169 } ,
170+ skip : ( page - 1 ) * this . perPage ,
171+ take : this . perPage + 1 ,
172+ } ) ;
173+
174+ const hasMore = queues . length > this . perPage ;
175+
176+ return {
177+ queues : await this . enrichQueues ( environment , queues . slice ( 0 , this . perPage ) ) ,
178+ hasMore,
179+ } ;
180+ }
181+
182+ private async getUnfilteredQueues (
183+ environment : AuthenticatedEnvironment ,
184+ page : number ,
185+ type : "task" | "custom" | undefined
186+ ) {
187+ const queues = await this . _replica . taskQueue . findMany ( {
188+ where : buildQueueListWhere ( environment . id , undefined , type ) ,
112189 select : {
113190 friendlyId : true ,
114191 name : true ,
@@ -127,12 +204,29 @@ export class QueueListPresenter extends BasePresenter {
127204 take : this . perPage ,
128205 } ) ;
129206
207+ return this . enrichQueues ( environment , queues ) ;
208+ }
209+
210+ private async enrichQueues (
211+ environment : AuthenticatedEnvironment ,
212+ queues : {
213+ friendlyId : string ;
214+ name : string ;
215+ orderableName : string | null ;
216+ concurrencyLimit : number | null ;
217+ concurrencyLimitBase : number | null ;
218+ concurrencyLimitOverriddenAt : Date | null ;
219+ concurrencyLimitOverriddenBy : string | null ;
220+ type : TaskQueueType ;
221+ paused : boolean ;
222+ } [ ]
223+ ) {
130224 const results = await Promise . all ( [
131- engine . lengthOfQueues (
225+ this . engineClient . lengthOfQueues (
132226 environment ,
133227 queues . map ( ( q ) => q . name )
134228 ) ,
135- engine . currentConcurrencyOfQueues (
229+ this . engineClient . currentConcurrencyOfQueues (
136230 environment ,
137231 queues . map ( ( q ) => q . name )
138232 ) ,
@@ -149,7 +243,6 @@ export class QueueListPresenter extends BasePresenter {
149243
150244 const overriddenByMap = new Map ( overriddenByUsers . map ( ( u ) => [ u . id , u ] ) ) ;
151245
152- // Transform queues to include running and queued counts
153246 return queues . map ( ( queue ) =>
154247 toQueueItem ( {
155248 friendlyId : queue . friendlyId ,
0 commit comments