99 lines
2.8 KiB
TypeScript
99 lines
2.8 KiB
TypeScript
import config from "@payload-config";
|
|
import { headers as nextHeaders } from "next/headers";
|
|
import { notFound, redirect } from "next/navigation";
|
|
import { getPayload } from "payload";
|
|
import { ReleasesView } from "@/components/frontend/projects/ReleasesView";
|
|
import { hasPermission } from "@/utils/access-control/hasPermission";
|
|
import { richTextToPlaintext } from "@/lib/projects/projectMeta";
|
|
|
|
export const metadata = {
|
|
title: "Releases: Polaris Task Force",
|
|
};
|
|
|
|
export default async function ReleasesPage({ params }: { params: Promise<{ key: string }> }) {
|
|
const { key } = await params;
|
|
const headers = await nextHeaders();
|
|
const payload = await getPayload({ config });
|
|
const { user } = await payload.auth({ headers, canSetHeaders: false });
|
|
|
|
if (!user) {
|
|
redirect(`/login?returnTo=/projects/${key}/releases`);
|
|
}
|
|
|
|
const projectResult = await payload.find({
|
|
collection: "projects" as any,
|
|
where: { key: { equals: key.toUpperCase() } },
|
|
limit: 1,
|
|
depth: 0,
|
|
overrideAccess: true,
|
|
});
|
|
|
|
if (projectResult.docs.length === 0) {
|
|
notFound();
|
|
}
|
|
|
|
const project = projectResult.docs[0] as any;
|
|
const canManage = await hasPermission(payload, user, "releases:update");
|
|
const canCreate = await hasPermission(payload, user, "releases:create");
|
|
|
|
const [releaseResult, ticketResult] = await Promise.all([
|
|
payload.find({
|
|
collection: "releases" as any,
|
|
where: { project: { equals: project.id } },
|
|
sort: "-releaseDate",
|
|
depth: 0,
|
|
limit: 100,
|
|
overrideAccess: true,
|
|
}),
|
|
payload.find({
|
|
collection: "tickets" as any,
|
|
where: { project: { equals: project.id } },
|
|
depth: 0,
|
|
limit: 500,
|
|
overrideAccess: true,
|
|
}),
|
|
]);
|
|
|
|
const tickets = ticketResult.docs as any[];
|
|
|
|
const releases = releaseResult.docs.map((r: any) => {
|
|
const releaseTickets = tickets.filter((ticket: any) => {
|
|
const releaseId =
|
|
typeof ticket.release === "object" && ticket.release !== null
|
|
? ticket.release.id
|
|
: ticket.release;
|
|
return releaseId === r.id;
|
|
});
|
|
|
|
const ticketsTotal = releaseTickets.length;
|
|
const ticketsResolved = releaseTickets.filter(
|
|
(ticket: any) => ticket.status === "resolved",
|
|
).length;
|
|
|
|
return {
|
|
id: r.id,
|
|
name: r.name,
|
|
status: r.status,
|
|
targetVersion: r.targetVersion,
|
|
releaseDate: r.releaseDate,
|
|
description: richTextToPlaintext(r.description) || null,
|
|
createdAt: r.createdAt,
|
|
ticketsTotal,
|
|
ticketsResolved,
|
|
};
|
|
});
|
|
|
|
return (
|
|
<div className="flex flex-col gap-6 p-5">
|
|
<ReleasesView
|
|
project={{
|
|
id: project.id,
|
|
name: project.name,
|
|
key: project.key,
|
|
}}
|
|
releases={releases}
|
|
isAdmin={canManage || canCreate}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|