feat: add bin tab to show soft deleted documents

This commit is contained in:
Ephraim Atta-Duncan
2024-05-30 19:51:28 +00:00
committed by Mythie
parent f31caaab08
commit c6393b7a9e
6 changed files with 125 additions and 47 deletions

View File

@ -115,6 +115,7 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
ExtendedDocumentStatus.PENDING, ExtendedDocumentStatus.PENDING,
ExtendedDocumentStatus.COMPLETED, ExtendedDocumentStatus.COMPLETED,
ExtendedDocumentStatus.DRAFT, ExtendedDocumentStatus.DRAFT,
ExtendedDocumentStatus.BIN,
ExtendedDocumentStatus.ALL, ExtendedDocumentStatus.ALL,
].map((value) => ( ].map((value) => (
<TabsTrigger <TabsTrigger

View File

@ -1,4 +1,4 @@
import { Bird, CheckCircle2 } from 'lucide-react'; import { Bird, CheckCircle2, Trash } from 'lucide-react';
import { match } from 'ts-pattern'; import { match } from 'ts-pattern';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status'; import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
@ -29,6 +29,11 @@ export const EmptyDocumentState = ({ status }: EmptyDocumentProps) => {
'You have not yet created or received any documents. To create a document please upload one.', 'You have not yet created or received any documents. To create a document please upload one.',
icon: Bird, icon: Bird,
})) }))
.with(ExtendedDocumentStatus.BIN, () => ({
title: 'No documents in the bin',
message: "There are no documents in the bin. You can't restore any documents.",
icon: Trash,
}))
.otherwise(() => ({ .otherwise(() => ({
title: 'Nothing to do', title: 'Nothing to do',
message: message:

View File

@ -1,6 +1,6 @@
import type { HTMLAttributes } from 'react'; import type { HTMLAttributes } from 'react';
import { CheckCircle2, Clock, File } from 'lucide-react'; import { CheckCircle2, Clock, File, TrashIcon } from 'lucide-react';
import type { LucideIcon } from 'lucide-react/dist/lucide-react'; import type { LucideIcon } from 'lucide-react/dist/lucide-react';
import type { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status'; import type { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
@ -38,6 +38,11 @@ export const FRIENDLY_STATUS_MAP: Record<ExtendedDocumentStatus, FriendlyStatus>
label: 'All', label: 'All',
color: 'text-muted-foreground', color: 'text-muted-foreground',
}, },
BIN: {
label: 'Bin',
icon: TrashIcon,
color: 'text-red-500 dark:text-red-200',
},
}; };
export type DocumentStatusProps = HTMLAttributes<HTMLSpanElement> & { export type DocumentStatusProps = HTMLAttributes<HTMLSpanElement> & {

View File

@ -94,57 +94,61 @@ export const findDocuments = async ({
}; };
} }
let deletedFilter: Prisma.DocumentWhereInput = { let deletedFilter: Prisma.DocumentWhereInput | undefined;
AND: {
OR: [
{
userId: user.id,
deletedAt: null,
},
{
Recipient: {
some: {
email: user.email,
documentDeletedAt: null,
},
},
},
],
},
};
if (team) { if (status !== ExtendedDocumentStatus.BIN) {
deletedFilter = { deletedFilter = {
AND: { AND: {
OR: team.teamEmail OR: [
? [ {
{ userId: user.id,
teamId: team.id, deletedAt: null,
deletedAt: null, },
{
Recipient: {
some: {
email: user.email,
documentDeletedAt: null,
}, },
{ },
User: { },
email: team.teamEmail.email, ],
},
deletedAt: null,
},
{
Recipient: {
some: {
email: team.teamEmail.email,
documentDeletedAt: null,
},
},
},
]
: [
{
teamId: team.id,
deletedAt: null,
},
],
}, },
}; };
if (team) {
deletedFilter = {
AND: {
OR: team.teamEmail
? [
{
teamId: team.id,
deletedAt: null,
},
{
User: {
email: team.teamEmail.email,
},
deletedAt: null,
},
{
Recipient: {
some: {
email: team.teamEmail.email,
documentDeletedAt: null,
},
},
},
]
: [
{
teamId: team.id,
deletedAt: null,
},
],
},
};
}
} }
const whereClause: Prisma.DocumentWhereInput = { const whereClause: Prisma.DocumentWhereInput = {
@ -298,6 +302,29 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
}, },
], ],
})) }))
.with(ExtendedDocumentStatus.BIN, () => ({
OR: [
{
userId: user.id,
teamId: null,
status: ExtendedDocumentStatus.COMPLETED,
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
{
status: ExtendedDocumentStatus.COMPLETED,
Recipient: {
some: {
email: user.email,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
},
},
],
}))
.exhaustive(); .exhaustive();
}; };
@ -477,5 +504,43 @@ const findTeamDocumentsFilter = (
return filter; return filter;
}) })
.with(ExtendedDocumentStatus.BIN, () => {
const filter: Prisma.DocumentWhereInput = {
OR: [
{
teamId: team.id,
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
],
};
if (teamEmail && filter.OR) {
filter.OR.push(
{
User: {
email: teamEmail,
},
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
{
Recipient: {
some: {
email: teamEmail,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
},
},
);
}
return filter;
})
.exhaustive(); .exhaustive();
}; };

View File

@ -36,6 +36,7 @@ export const getStats = async ({ user, period, ...options }: GetStatsInput) => {
[ExtendedDocumentStatus.COMPLETED]: 0, [ExtendedDocumentStatus.COMPLETED]: 0,
[ExtendedDocumentStatus.INBOX]: 0, [ExtendedDocumentStatus.INBOX]: 0,
[ExtendedDocumentStatus.ALL]: 0, [ExtendedDocumentStatus.ALL]: 0,
[ExtendedDocumentStatus.BIN]: 0,
}; };
ownerCounts.forEach((stat) => { ownerCounts.forEach((stat) => {

View File

@ -4,6 +4,7 @@ export const ExtendedDocumentStatus = {
...DocumentStatus, ...DocumentStatus,
INBOX: 'INBOX', INBOX: 'INBOX',
ALL: 'ALL', ALL: 'ALL',
BIN: 'BIN',
} as const; } as const;
export type ExtendedDocumentStatus = export type ExtendedDocumentStatus =