d1092fcd2c
* Run filtering is now shared: runs page and job runs page * Use optimistic location * Improved the type in the run status filter dropdown * Organize imports
118 lines
2.8 KiB
TypeScript
118 lines
2.8 KiB
TypeScript
import { Direction } from "~/components/runs/RunStatuses";
|
|
import { PrismaClient, prisma } from "~/db.server";
|
|
|
|
type RunListOptions = {
|
|
userId: string;
|
|
webhookId: string;
|
|
direction?: Direction;
|
|
cursor?: string;
|
|
};
|
|
|
|
const PAGE_SIZE = 20;
|
|
|
|
export type WebhookDeliveryList = Awaited<ReturnType<WebhookDeliveryListPresenter["call"]>>;
|
|
|
|
export class WebhookDeliveryListPresenter {
|
|
#prismaClient: PrismaClient;
|
|
|
|
constructor(prismaClient: PrismaClient = prisma) {
|
|
this.#prismaClient = prismaClient;
|
|
}
|
|
|
|
public async call({ userId, webhookId, direction = "forward", cursor }: RunListOptions) {
|
|
const directionMultiplier = direction === "forward" ? 1 : -1;
|
|
|
|
const runs = await this.#prismaClient.webhookRequestDelivery.findMany({
|
|
select: {
|
|
id: true,
|
|
number: true,
|
|
createdAt: true,
|
|
deliveredAt: true,
|
|
verified: true,
|
|
error: true,
|
|
environment: {
|
|
select: {
|
|
type: true,
|
|
slug: true,
|
|
orgMember: {
|
|
select: {
|
|
userId: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
where: {
|
|
webhookId,
|
|
environment: {
|
|
OR: [
|
|
{
|
|
orgMember: null,
|
|
},
|
|
{
|
|
orgMember: {
|
|
userId,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
orderBy: [{ id: "desc" }],
|
|
//take an extra page to tell if there are more
|
|
take: directionMultiplier * (PAGE_SIZE + 1),
|
|
//skip the cursor if there is one
|
|
skip: cursor ? 1 : 0,
|
|
cursor: cursor
|
|
? {
|
|
id: cursor,
|
|
}
|
|
: undefined,
|
|
});
|
|
|
|
const hasMore = runs.length > PAGE_SIZE;
|
|
|
|
//get cursors for next and previous pages
|
|
let next: string | undefined;
|
|
let previous: string | undefined;
|
|
switch (direction) {
|
|
case "forward":
|
|
previous = cursor ? runs.at(0)?.id : undefined;
|
|
if (hasMore) {
|
|
next = runs[PAGE_SIZE - 1]?.id;
|
|
}
|
|
break;
|
|
case "backward":
|
|
if (hasMore) {
|
|
previous = runs[1]?.id;
|
|
next = runs[PAGE_SIZE]?.id;
|
|
} else {
|
|
next = runs[PAGE_SIZE - 1]?.id;
|
|
}
|
|
break;
|
|
}
|
|
|
|
const runsToReturn =
|
|
direction === "backward" && hasMore ? runs.slice(1, PAGE_SIZE + 1) : runs.slice(0, PAGE_SIZE);
|
|
|
|
return {
|
|
runs: runsToReturn.map((run) => ({
|
|
id: run.id,
|
|
number: run.number,
|
|
createdAt: run.createdAt,
|
|
deliveredAt: run.deliveredAt,
|
|
verified: run.verified,
|
|
error: run.error,
|
|
environment: {
|
|
type: run.environment.type,
|
|
slug: run.environment.slug,
|
|
userId: run.environment.orgMember?.userId,
|
|
},
|
|
})),
|
|
pagination: {
|
|
next,
|
|
previous,
|
|
},
|
|
};
|
|
}
|
|
}
|