import { type LoaderFunctionArgs } from "@remix-run/server-runtime"; import { z } from "zod"; import { findProjectBySlug } from "~/models/project.server"; import { findEnvironmentBySlug } from "~/models/runtimeEnvironment.server"; import { QueueListPresenter } from "~/presenters/v3/QueueListPresenter.server"; import { requireUserId } from "~/services/session.server"; import { EnvironmentParamSchema } from "~/utils/pathBuilder"; const SearchParamsSchema = z.object({ query: z.string().optional(), page: z.coerce.number().min(1).default(1), per_page: z.coerce.number().min(1).default(20), type: z.enum(["task", "custom"]).optional(), }); export async function loader({ request, params }: LoaderFunctionArgs) { const userId = await requireUserId(request); const { organizationSlug, projectParam, envParam } = EnvironmentParamSchema.parse(params); const url = new URL(request.url); const { page, per_page, query, type } = SearchParamsSchema.parse( Object.fromEntries(url.searchParams) ); const project = await findProjectBySlug(organizationSlug, projectParam, userId); if (!project) { throw new Response(undefined, { status: 404, statusText: "Project not found", }); } const environment = await findEnvironmentBySlug(project.id, envParam, userId); if (!environment) { throw new Response(undefined, { status: 404, statusText: "Environment not found", }); } const presenter = new QueueListPresenter(per_page); const result = await presenter.call({ environment: environment, query, page, type, }); if (!result.success) { return { queues: [], currentPage: 1, hasMore: false, hasFilters: Boolean(query?.trim()) || Boolean(type), }; } return { queues: result.queues.map((queue) => ({ id: queue.id, name: queue.name, type: queue.type, paused: queue.paused, })), currentPage: result.pagination.currentPage, hasMore: result.pagination.mode === "filtered" ? result.pagination.hasMore : result.pagination.currentPage < result.pagination.totalPages, hasFilters: result.hasFilters, }; }