-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Transcription Management page to handle the transcription process. The page features two tables: one for the transcription backlog and another for the transcription queue. Items from the backlog can be added to the queue for transcription. After transcription starts, it provides visibility on the state of active transcription jobs. Note: There is currently no visibility on past transcription jobs.
- Loading branch information
Showing
12 changed files
with
571 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { | ||
Button, | ||
Flex, | ||
Menu, | ||
MenuButton, | ||
MenuItem, | ||
MenuList, | ||
Text, | ||
} from "@chakra-ui/react"; | ||
import { MdArrowDropDown } from "react-icons/md"; | ||
|
||
const SelectSourceMenu = ({ | ||
isLoading, | ||
sources, | ||
onSelection: selectSource, | ||
}: { | ||
isLoading?: boolean; | ||
sources?: string[]; | ||
onSelection: (source: string) => void; | ||
}) => ( | ||
<Menu> | ||
<MenuButton | ||
as={Button} | ||
isLoading={isLoading} | ||
aria-label="select source" | ||
colorScheme="orange" | ||
> | ||
<Flex gap={2} alignItems={"center"}> | ||
<Text> Select Source </Text> | ||
<MdArrowDropDown size={20} /> | ||
</Flex> | ||
</MenuButton> | ||
<MenuList color="black"> | ||
{sources && | ||
sources.map((source) => ( | ||
<MenuItem | ||
key={source} | ||
onClick={() => { | ||
selectSource(source); | ||
}} | ||
> | ||
{source} | ||
</MenuItem> | ||
))} | ||
</MenuList> | ||
</Menu> | ||
); | ||
|
||
export default SelectSourceMenu; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as SelectSourceMenu } from "./SelectSourceMenu" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
import { useState } from "react"; | ||
import { Button, Flex, Heading, Text } from "@chakra-ui/react"; | ||
|
||
import { useHasPermission } from "@/hooks/useHasPermissions"; | ||
import AuthStatus from "@/components/transcript/AuthStatus"; | ||
import { | ||
useTranscriptionQueue, | ||
useTranscriptionBacklog, | ||
} from "@/services/api/admin"; | ||
import { SelectSourceMenu } from "@/components/tables/components"; | ||
|
||
import BaseTable from "@/components/tables/BaseTable"; | ||
import { convertStringToArray } from "@/utils"; | ||
import TitleWithTags from "@/components/tables/TitleWithTags"; | ||
import { TableStructure } from "@/components/tables/types"; | ||
import { TranscriptMetadata, TranscriptionQueueItem } from "../../../types"; | ||
|
||
const Sources = () => { | ||
const [selectedSource, setSelectedSource] = useState<string>("all"); | ||
const [removeFromQueueSelection, setRemoveFromQueueSelection] = useState< | ||
string[] | ||
>([]); | ||
const [addToQueueSelection, setAddToQueueSelection] = useState<string[]>([]); | ||
const canAccessTranscription = useHasPermission("accessTranscription"); | ||
|
||
const { transcriptionBacklog, sources } = | ||
useTranscriptionBacklog(selectedSource); | ||
const { | ||
transcriptionQueue, | ||
remainingBacklog, | ||
addToQueue, | ||
removeFromQueue, | ||
startTranscription, | ||
isTranscribing, | ||
refetch, | ||
} = useTranscriptionQueue(transcriptionBacklog.data); | ||
|
||
const handleAddToQueue = async () => { | ||
await addToQueue.mutateAsync(addToQueueSelection); | ||
setAddToQueueSelection([]); | ||
}; | ||
|
||
const handleRemoveFromQueue = async () => { | ||
await removeFromQueue.mutateAsync(removeFromQueueSelection); | ||
setRemoveFromQueueSelection([]); | ||
}; | ||
|
||
const tableStructure = [ | ||
{ | ||
name: "Title", | ||
type: "default", | ||
modifier: () => null, | ||
component: (data) => { | ||
const allTags = convertStringToArray(data.tags); | ||
return ( | ||
<TitleWithTags | ||
title={data.title} | ||
allTags={allTags} | ||
categories={[]} | ||
loc={data.loc} | ||
url={data.media} | ||
id={0} | ||
length={allTags.length} | ||
shouldSlice={false} | ||
/> | ||
); | ||
}, | ||
}, | ||
{ | ||
name: "speakers", | ||
type: "text-long", | ||
modifier: (data) => data.speakers.join(", "), | ||
}, | ||
{ name: "Publish Date", type: "text-short", modifier: (data) => data.date }, | ||
] satisfies TableStructure<TranscriptMetadata>[]; | ||
|
||
const transcriptionQueueTableStructure = [ | ||
...tableStructure, | ||
{ | ||
name: "status", | ||
type: "text-short", | ||
modifier: (data) => data.status, | ||
}, | ||
] satisfies TableStructure<TranscriptionQueueItem>[]; | ||
|
||
if (!canAccessTranscription) { | ||
return ( | ||
<AuthStatus | ||
title="Unauthorized" | ||
message="You are not authorized to access this page" | ||
/> | ||
); | ||
} | ||
|
||
return ( | ||
<> | ||
<Flex flexDir="column"> | ||
<Heading size={"md"} mb={10}> | ||
{`Transcription Management`} | ||
</Heading> | ||
<BaseTable | ||
data={transcriptionQueue.data} | ||
emptyView={ | ||
<Flex w="full" justifyContent="center" alignItems="center" gap={2}> | ||
<Text>Transcription queue is empty</Text> | ||
</Flex> | ||
} | ||
isLoading={transcriptionQueue.isLoading} | ||
isError={transcriptionQueue.isError} | ||
tableStructure={transcriptionQueueTableStructure} | ||
tableHeaderComponent={ | ||
<Heading size="sm" mb={1}> | ||
Transcription Queue | ||
</Heading> | ||
} | ||
enableCheckboxes={!isTranscribing} | ||
selectedRowIds={removeFromQueueSelection} | ||
onSelectedRowIdsChange={setRemoveFromQueueSelection} | ||
getRowId={(row) => row.media} | ||
refetch={refetch} | ||
actionItems={ | ||
<> | ||
{!isTranscribing && ( | ||
<Button | ||
isDisabled={removeFromQueueSelection.length == 0} | ||
isLoading={removeFromQueue.isLoading} | ||
onClick={handleRemoveFromQueue} | ||
> | ||
Remove from Queue | ||
</Button> | ||
)} | ||
<Button | ||
isDisabled={ | ||
transcriptionBacklog.isLoading || | ||
transcriptionQueue.data?.length == 0 || | ||
isTranscribing | ||
} | ||
onClick={() => startTranscription.mutate()} | ||
> | ||
{`${ | ||
isTranscribing | ||
? "Transcription in Progress..." | ||
: "Start Transcription" | ||
}`} | ||
</Button> | ||
</> | ||
} | ||
/> | ||
<BaseTable | ||
data={remainingBacklog} | ||
emptyView={ | ||
<Flex w="full" justifyContent="center" alignItems="center" gap={2}> | ||
<Text> | ||
Transcription backlog is empty for the selected source | ||
</Text> | ||
</Flex> | ||
} | ||
isLoading={transcriptionBacklog.isLoading} | ||
isError={transcriptionBacklog.isError} | ||
tableStructure={tableStructure} | ||
tableHeaderComponent={ | ||
<Heading size="sm" mb={1}> | ||
{`Transcription Backlog (${selectedSource})`} | ||
</Heading> | ||
} | ||
enableCheckboxes | ||
selectedRowIds={addToQueueSelection} | ||
onSelectedRowIdsChange={setAddToQueueSelection} | ||
getRowId={(row) => row.media} | ||
actionItems={ | ||
<> | ||
<Button | ||
isLoading={addToQueue.isLoading} | ||
isDisabled={addToQueueSelection.length == 0} | ||
onClick={handleAddToQueue} | ||
> | ||
Add to Queue | ||
</Button> | ||
<SelectSourceMenu | ||
sources={sources.data} | ||
isLoading={sources.isLoading} | ||
onSelection={(source: string) => setSelectedSource(source)} | ||
/> | ||
</> | ||
} | ||
/> | ||
</Flex> | ||
</> | ||
); | ||
}; | ||
|
||
export default Sources; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
export * from "./useTransaction"; | ||
export * from "./useReviews"; | ||
export * from "./useUsers"; | ||
export * from "./useTranscriptionQueue"; | ||
export * from "./useTranscriptionBacklog"; |
Oops, something went wrong.