feat: delete recording with transcript (#547)

* Delete recording with transcript

* Delete confirmation dialog

* Use aws storage abstraction for recording deletion

* Test recording deleted with transcript

* Use get transcript storage

* Fix the test

* Add env vars for recording storage
This commit is contained in:
2025-08-14 20:45:30 +02:00
committed by GitHub
parent 9eab952c63
commit b9d891d342
9 changed files with 182 additions and 42 deletions

View File

@@ -1,12 +1,15 @@
import React from "react";
import { Button } from "@chakra-ui/react";
// import { Dialog } from "@chakra-ui/react";
import { Button, Dialog, Text } from "@chakra-ui/react";
interface DeleteTranscriptDialogProps {
isOpen: boolean;
onClose: () => void;
onConfirm: () => void;
cancelRef: React.RefObject<any>;
isLoading?: boolean;
title?: string;
date?: string;
source?: string;
}
export default function DeleteTranscriptDialog({
@@ -14,35 +17,65 @@ export default function DeleteTranscriptDialog({
onClose,
onConfirm,
cancelRef,
isLoading,
title,
date,
source,
}: DeleteTranscriptDialogProps) {
// Temporarily return null to fix import issues
return null;
/* return (
return (
<Dialog.Root
open={isOpen}
onOpenChange={(e) => !e.open && onClose()}
onOpenChange={(e) => {
if (!e.open) onClose();
}}
initialFocusEl={() => cancelRef.current}
>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header fontSize="lg" fontWeight="bold">
Delete Transcript
Delete transcript
</Dialog.Header>
<Dialog.Body>
Are you sure? You can't undo this action afterwards.
Are you sure you want to delete this transcript? This action cannot
be undone.
{title && (
<Text mt={3} fontWeight="600">
{title}
</Text>
)}
{date && (
<Text color="gray.600" fontSize="sm">
Date: {date}
</Text>
)}
{source && (
<Text color="gray.600" fontSize="sm">
Source: {source}
</Text>
)}
</Dialog.Body>
<Dialog.Footer>
<Button ref={cancelRef} onClick={onClose}>
<Button
ref={cancelRef as any}
onClick={onClose}
disabled={!!isLoading}
variant="outline"
colorPalette="gray"
>
Cancel
</Button>
<Button colorPalette="red" onClick={onConfirm} ml={3}>
<Button
colorPalette="red"
onClick={onConfirm}
ml={3}
disabled={!!isLoading}
>
Delete
</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
); */
);
}

View File

@@ -13,6 +13,7 @@ import SearchBar from "./_components/SearchBar";
import TranscriptTable from "./_components/TranscriptTable";
import TranscriptCards from "./_components/TranscriptCards";
import DeleteTranscriptDialog from "./_components/DeleteTranscriptDialog";
import { formatLocalDate } from "../../lib/time";
export default function TranscriptBrowser() {
const [selectedSourceKind, setSelectedSourceKind] =
@@ -25,7 +26,7 @@ export default function TranscriptBrowser() {
page,
selectedSourceKind,
selectedRoomId,
searchTerm,
searchTerm
);
const userName = useSessionUser().name;
const [deletionLoading, setDeletionLoading] = useState(false);
@@ -50,7 +51,7 @@ export default function TranscriptBrowser() {
const handleFilterTranscripts = (
sourceKind: SourceKind | null,
roomId: string,
roomId: string
) => {
setSelectedSourceKind(sourceKind);
setSelectedRoomId(roomId);
@@ -96,26 +97,28 @@ export default function TranscriptBrowser() {
const onCloseDeletion = () => setTranscriptToDeleteId(undefined);
const handleDeleteTranscript = (transcriptId) => (e) => {
e.stopPropagation();
if (api && !deletionLoading) {
setDeletionLoading(true);
api
.v1TranscriptDelete({ transcriptId })
.then(() => {
refetch();
setDeletionLoading(false);
onCloseDeletion();
setDeletedItemIds((deletedItemIds) => [
deletedItemIds,
...transcriptId,
]);
})
.catch((err) => {
setDeletionLoading(false);
setError(err, "There was an error deleting the transcript");
});
}
const confirmDeleteTranscript = (transcriptId: string) => {
if (!api || deletionLoading) return;
setDeletionLoading(true);
api
.v1TranscriptDelete({ transcriptId })
.then(() => {
refetch();
setDeletionLoading(false);
onCloseDeletion();
setDeletedItemIds((prev) =>
prev ? [...prev, transcriptId] : [transcriptId]
);
})
.catch((err) => {
setDeletionLoading(false);
setError(err, "There was an error deleting the transcript");
});
};
const handleDeleteTranscript = (transcriptId: string) => (e: any) => {
e?.stopPropagation?.();
setTranscriptToDeleteId(transcriptId);
};
const handleProcessTranscript = (transcriptId) => (e) => {
@@ -127,7 +130,7 @@ export default function TranscriptBrowser() {
if (status === "already running") {
setError(
new Error("Processing is already running, please wait"),
"Processing is already running, please wait",
"Processing is already running, please wait"
);
}
})
@@ -137,6 +140,19 @@ export default function TranscriptBrowser() {
}
};
const transcriptToDelete = response?.items?.find(
(i) => i.id === transcriptToDeleteId
);
const dialogTitle = transcriptToDelete?.title || "Unnamed Transcript";
const dialogDate = transcriptToDelete?.created_at
? formatLocalDate(transcriptToDelete.created_at)
: undefined;
const dialogSource = transcriptToDelete
? transcriptToDelete.source_kind === "room"
? transcriptToDelete.room_name || undefined
: transcriptToDelete.source_kind
: undefined;
return (
<Flex
flexDir="column"
@@ -197,8 +213,14 @@ export default function TranscriptBrowser() {
<DeleteTranscriptDialog
isOpen={!!transcriptToDeleteId}
onClose={onCloseDeletion}
onConfirm={() => handleDeleteTranscript(transcriptToDeleteId)(null)}
onConfirm={() =>
transcriptToDeleteId && confirmDeleteTranscript(transcriptToDeleteId)
}
cancelRef={cancelRef}
isLoading={deletionLoading}
title={dialogTitle}
date={dialogDate}
source={dialogSource}
/>
</Flex>
);