diff --git a/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx b/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx new file mode 100644 index 000000000..3f13516df --- /dev/null +++ b/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx @@ -0,0 +1,172 @@ +/* eslint-disable react/no-unstable-nested-components */ + +import { Button, CellHeader } from '@czi-sds/components' +import { ColumnDef, createColumnHelper } from '@tanstack/react-table' +import { range } from 'lodash-es' +import { useMemo } from 'react' + +import { GetRunByIdQuery } from 'app/__generated__/graphql' +import { MAX_PER_PAGE } from 'app/constants/pagination' +import { useIsLoading } from 'app/hooks/useIsLoading' +import { useRunById } from 'app/hooks/useRunById' +import { i18n } from 'app/i18n' +import { useDrawer } from 'app/state/drawer' +import { cnsNoMerge } from 'app/utils/cns' + +import { Table, TableCell } from '../Table' + +type Annotation = + GetRunByIdQuery['runs'][number]['annotation_table'][number]['annotations'][number] + +const LOADING_ANNOTATIONS = range(0, MAX_PER_PAGE).map(() => ({}) as Annotation) + +function ConfidenceValue({ value }: { value: number }) { + return ( +
+

{value}%

+

+ {i18n.confidence} +

+
+ ) +} + +export function AnnotationTable() { + const { isLoadingDebounced } = useIsLoading() + const { run } = useRunById() + const drawer = useDrawer() + + const columns = useMemo(() => { + const columnHelper = createColumnHelper() + + function getConfidenceCell(key: keyof Annotation, header: string) { + return columnHelper.accessor(key, { + header: () => {header}, + cell: ({ getValue }) => { + const value = getValue() as number | null + + return ( + + {typeof value === 'number' ? ( + + ) : ( +

+ {i18n.na} +

+ )} +
+ ) + }, + }) + } + + return [ + columnHelper.accessor('s3_annotations_path', { + header: i18n.annotations, + cell: ({ row: { original: annotation } }) => ( + +
+

+ {annotation.s3_annotations_path?.split('/').at(-1) ?? '--'} +

+ + {annotation.ground_truth_status && ( +
+ {i18n.groundTruth} +
+ )} +
+ + +
+ ), + }), + + columnHelper.accessor('object_name', { + header: i18n.annotationObject, + cell: ({ getValue }) => ( + + {getValue()} + + ), + }), + + columnHelper.accessor('object_count', { + header: () => ( + {i18n.objectCount} + ), + cell: ({ getValue }) => ( + + {getValue()} + + ), + }), + + getConfidenceCell('confidence_precision', i18n.precision), + getConfidenceCell('confidence_recall', i18n.recall), + + columnHelper.display({ + id: 'annotation-actions', + // Render empty cell header so that it doesn't break the table layout + header: () => {null}, + cell: () => ( + + + + ), + }), + ] as ColumnDef[] + }, [drawer.toggle]) + + const annotations = run.annotation_table.flatMap( + (data) => data.annotations, + ) as unknown as Annotation[] + + return ( + + ) +}