a83edb2f9d
Redesigned timeline project and resource panels with expanded detail views, added quick filter toolbar, improved drag handling, and enhanced vacation/entitlement router logic. Includes e2e test updates and minor API fixes. Co-Authored-By: claude-flow <ruv@ruv.net>
105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
import type { Prisma, PrismaClient } from "@planarchy/db";
|
|
|
|
type AssignmentBookingsDbClient = Pick<PrismaClient, "assignment">;
|
|
|
|
export interface ListAssignmentBookingsInput {
|
|
startDate?: Date | undefined;
|
|
endDate?: Date | undefined;
|
|
resourceIds?: string[] | undefined;
|
|
projectIds?: string[] | undefined;
|
|
excludeAssignmentIds?: string[] | undefined;
|
|
}
|
|
|
|
export interface AssignmentBookingWithFallback {
|
|
id: string;
|
|
projectId: string;
|
|
resourceId: string | null;
|
|
startDate: Date;
|
|
endDate: Date;
|
|
hoursPerDay: number;
|
|
dailyCostCents: number;
|
|
status: string;
|
|
project: {
|
|
id: string;
|
|
name: string;
|
|
shortCode: string;
|
|
status: string;
|
|
orderType: string;
|
|
clientId: string | null;
|
|
dynamicFields: Prisma.JsonValue | null;
|
|
};
|
|
resource: {
|
|
id: string;
|
|
displayName: string;
|
|
chapter: string | null;
|
|
} | null;
|
|
}
|
|
|
|
export async function listAssignmentBookings(
|
|
db: AssignmentBookingsDbClient,
|
|
input: ListAssignmentBookingsInput,
|
|
): Promise<AssignmentBookingWithFallback[]> {
|
|
const hasDateBounds = input.startDate !== undefined && input.endDate !== undefined;
|
|
if (!hasDateBounds && (input.startDate !== undefined || input.endDate !== undefined)) {
|
|
throw new Error("startDate and endDate must be provided together");
|
|
}
|
|
|
|
const excludeAssignmentIds = input.excludeAssignmentIds?.filter(Boolean) ?? [];
|
|
|
|
const assignmentWhere = {
|
|
status: { not: "CANCELLED" as const },
|
|
...(hasDateBounds
|
|
? {
|
|
startDate: { lte: input.endDate! },
|
|
endDate: { gte: input.startDate! },
|
|
}
|
|
: {}),
|
|
...(input.resourceIds?.length ? { resourceId: { in: input.resourceIds } } : {}),
|
|
...(input.projectIds?.length ? { projectId: { in: input.projectIds } } : {}),
|
|
...(excludeAssignmentIds.length ? { id: { notIn: excludeAssignmentIds } } : {}),
|
|
} satisfies Prisma.AssignmentWhereInput;
|
|
|
|
const assignmentSelect = {
|
|
id: true,
|
|
projectId: true,
|
|
resourceId: true,
|
|
startDate: true,
|
|
endDate: true,
|
|
hoursPerDay: true,
|
|
dailyCostCents: true,
|
|
status: true,
|
|
project: {
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
shortCode: true,
|
|
status: true,
|
|
orderType: true,
|
|
clientId: true,
|
|
dynamicFields: true,
|
|
},
|
|
},
|
|
resource: {
|
|
select: { id: true, displayName: true, chapter: true },
|
|
},
|
|
} satisfies Prisma.AssignmentSelect;
|
|
|
|
const assignments = await db.assignment.findMany({
|
|
where: assignmentWhere,
|
|
select: assignmentSelect,
|
|
});
|
|
|
|
return assignments.map((assignment) => ({
|
|
id: assignment.id,
|
|
projectId: assignment.projectId,
|
|
resourceId: assignment.resourceId,
|
|
startDate: assignment.startDate,
|
|
endDate: assignment.endDate,
|
|
hoursPerDay: assignment.hoursPerDay,
|
|
dailyCostCents: assignment.dailyCostCents,
|
|
status: assignment.status,
|
|
project: assignment.project,
|
|
resource: assignment.resource,
|
|
}));
|
|
}
|