Files
documenso/packages/lib/server-only/template/find-templates.ts
T
ephraimduncan 335fee09a9 feat: add faceted table toolbars and multi-value filters
Consolidating document and template filtering into shared faceted
toolbars makes filtering easier to discover and use.
Supporting comma-separated query params enables multi-select filters
across UI, server queries, and E2E coverage.
2026-02-16 18:40:23 +00:00

127 lines
2.6 KiB
TypeScript

import type { TemplateType } from '@prisma/client';
import { EnvelopeType, type Prisma } from '@prisma/client';
import { prisma } from '@documenso/prisma';
import { TEAM_DOCUMENT_VISIBILITY_MAP } from '../../constants/teams';
import { type FindResultResponse } from '../../types/search-params';
import { getMemberRoles } from '../team/get-member-roles';
export type FindTemplatesOptions = {
userId: number;
teamId: number;
type?: TemplateType | TemplateType[];
query?: string;
page?: number;
perPage?: number;
folderId?: string;
};
export const findTemplates = async ({
userId,
teamId,
type,
query = '',
page = 1,
perPage = 10,
folderId,
}: FindTemplatesOptions) => {
const whereFilter: Prisma.EnvelopeWhereInput[] = [];
const templateTypeFilter = type ? { in: Array.isArray(type) ? type : [type] } : undefined;
const { teamRole } = await getMemberRoles({
teamId,
reference: {
type: 'User',
id: userId,
},
});
whereFilter.push(
{ teamId },
{
OR: [
{
visibility: {
in: TEAM_DOCUMENT_VISIBILITY_MAP[teamRole],
},
},
{ userId, teamId },
],
},
);
if (folderId) {
whereFilter.push({ folderId });
} else {
whereFilter.push({ folderId: null });
}
if (query) {
whereFilter.push({
OR: [
{
title: {
contains: query,
mode: 'insensitive',
},
},
{
externalId: {
contains: query,
mode: 'insensitive',
},
},
],
});
}
const [data, count] = await Promise.all([
prisma.envelope.findMany({
where: {
type: EnvelopeType.TEMPLATE,
templateType: templateTypeFilter,
AND: whereFilter,
},
include: {
team: {
select: {
id: true,
url: true,
},
},
fields: true,
recipients: true,
documentMeta: true,
directLink: {
select: {
token: true,
enabled: true,
},
},
},
skip: Math.max(page - 1, 0) * perPage,
take: perPage,
orderBy: {
createdAt: 'desc',
},
}),
prisma.envelope.count({
where: {
type: EnvelopeType.TEMPLATE,
templateType: templateTypeFilter,
AND: whereFilter,
},
}),
]);
return {
data,
count,
currentPage: Math.max(page, 1),
perPage,
totalPages: Math.ceil(count / perPage),
} satisfies FindResultResponse<typeof data>;
};