diff --git a/app/occurrences/[occurrence_id]/page.tsx b/app/occurrences/[occurrence_id]/page.tsx index 6447a2ed..c9733a5b 100644 --- a/app/occurrences/[occurrence_id]/page.tsx +++ b/app/occurrences/[occurrence_id]/page.tsx @@ -9,6 +9,7 @@ import BookmarkButton from '@/components/occurrence/BookmarkButton'; import Context from '@/components/occurrence/Context'; import Environment from '@/components/occurrence/Environment'; import Params from '@/components/occurrence/Params'; +import ResolveButton from '@/components/occurrence/ResolveButton'; import Session from '@/components/occurrence/Session'; import Toolbox from '@/components/occurrence/Toolbox'; import ProjectActionsMenu from '@/components/project/ActionsMenu'; @@ -164,6 +165,7 @@ export default async function Occurrence({ params, searchParams }: ComponentProp

Last seen: {occurrence.updated_at.toUTCString()}

+ diff --git a/components/OccurrencesTable.tsx b/components/OccurrencesTable.tsx index a17dd224..87b601a5 100644 --- a/components/OccurrencesTable.tsx +++ b/components/OccurrencesTable.tsx @@ -35,6 +35,12 @@ export default async function OccurrencesTable({ noticeId, searchParams }: Occur + {occurrence.resolved_at && ( +
+ resolved +
+ )} +

First seen:

diff --git a/components/occurrence/ResolveButton.tsx b/components/occurrence/ResolveButton.tsx new file mode 100644 index 00000000..e4bfb51d --- /dev/null +++ b/components/occurrence/ResolveButton.tsx @@ -0,0 +1,26 @@ +'use client'; + +import { reinstateOccurrence, resolveOccurrence } from '@/app/_actions'; +import { useTransition } from 'react'; + +export default function ResolveButton({ occurrenceId, resolvedAt }: { occurrenceId: string; resolvedAt: Date | null }) { + let [isPending, startTransition] = useTransition(); + + return resolvedAt ? ( + + ) : ( + + ); +} diff --git a/lib/actions/occurrenceActions.ts b/lib/actions/occurrenceActions.ts index 7586f39b..73610555 100644 --- a/lib/actions/occurrenceActions.ts +++ b/lib/actions/occurrenceActions.ts @@ -86,3 +86,21 @@ export async function removeOccurrenceBookmark(occurrenceId: string) { revalidatePath(`/occurrences/${occurrenceId}`) revalidatePath('/bookmarks') } + +export async function resolveOccurrence(occurrenceId: string) { + await prisma.occurrence.update({ + where: { id: occurrenceId }, + data: { resolved_at: new Date() }, + }); + + revalidatePath(`/occurrences/${occurrenceId}`); +} + +export async function reinstateOccurrence(occurrenceId: string) { + await prisma.occurrence.update({ + where: { id: occurrenceId }, + data: { resolved_at: null }, + }); + + revalidatePath(`/occurrences/${occurrenceId}`); +} diff --git a/lib/processError.ts b/lib/processError.ts index fabf9df3..ba16d619 100644 --- a/lib/processError.ts +++ b/lib/processError.ts @@ -86,6 +86,7 @@ export async function processError( }, }, update: { + resolved_at: null, // auto reinstate // we've seen updated_at work here seen_count: { increment: 1, diff --git a/prisma/migrations/20230608180606_add_resolved_at/migration.sql b/prisma/migrations/20230608180606_add_resolved_at/migration.sql new file mode 100644 index 00000000..491d76d0 --- /dev/null +++ b/prisma/migrations/20230608180606_add_resolved_at/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "occurrences" ADD COLUMN "resolved_at" TIMESTAMP(6); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 016fc1d1..5f6cb0db 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -59,6 +59,7 @@ model Occurrence { params Json @default("{}") created_at DateTime @default(now()) @db.Timestamp(6) updated_at DateTime @updatedAt @db.Timestamp(6) + resolved_at DateTime? @db.Timestamp(6) notice Notice @relation(fields: [notice_id], references: [id], onDelete: Cascade) hourly_occurrences HourlyOccurrence[] bookmarks OccurrenceBookmark[]