From 61642016fd90f8b64f6a0d94d7885be07f5bb871 Mon Sep 17 00:00:00 2001 From: Jeremy Asuncion Date: Wed, 2 Oct 2024 11:16:23 -0700 Subject: [PATCH] feat: update annotation row name (#1163) #1050 - Updates the annotation row name to be in the format `{file_id} - {object_name}` - Add annotation ID + move ground truth badge - Adds new annotation name to download modal ## Demo https://dev-annotation-row-name.cryoet.dev.si.czi.technology/ image image image --- .../Download/ConfigureDownloadContent.tsx | 6 +- .../Download/DownloadOptionsContent.tsx | 4 + .../app/components/Run/AnnotationTable.tsx | 74 +++++++++++++------ .../data-portal/app/constants/query.ts | 1 + .../app/graphql/getRunById.server.ts | 1 + .../hooks/useDownloadModalQueryParamState.ts | 8 ++ .../data-portal/app/hooks/usePlausible.ts | 1 + .../data-portal/app/state/annotation.ts | 5 +- .../public/locales/en/translation.json | 15 ++-- 9 files changed, 82 insertions(+), 33 deletions(-) diff --git a/frontend/packages/data-portal/app/components/Download/ConfigureDownloadContent.tsx b/frontend/packages/data-portal/app/components/Download/ConfigureDownloadContent.tsx index f5f95f935..2f3546d84 100644 --- a/frontend/packages/data-portal/app/components/Download/ConfigureDownloadContent.tsx +++ b/frontend/packages/data-portal/app/components/Download/ConfigureDownloadContent.tsx @@ -10,12 +10,16 @@ import { ConfigureTomogramDownloadContent } from './ConfigureTomogramDownloadCon export function ConfigureDownloadContent() { const { t } = useI18n() const { datasetTitle, runName, objectName } = useDownloadModalContext() - const { annotationId, objectShapeType } = useDownloadModalQueryParamState() + const { annotationName, annotationId, objectShapeType } = + useDownloadModalQueryParamState() return ( <> {runName && } + {annotationName && ( + + )} {annotationId && ( )} + {annotationName && ( + + )} {annotationId && ( )} diff --git a/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx b/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx index e0bed471b..b70d02013 100644 --- a/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx +++ b/frontend/packages/data-portal/app/components/Run/AnnotationTable.tsx @@ -1,6 +1,7 @@ /* eslint-disable react/no-unstable-nested-components */ import { Button, Icon } from '@czi-sds/components' +import Skeleton from '@mui/material/Skeleton' import { useSearchParams } from '@remix-run/react' import { ColumnDef, @@ -15,6 +16,7 @@ import { AuthorList } from 'app/components/AuthorList' import { I18n } from 'app/components/I18n' import { CellHeader, PageTable, TableCell } from 'app/components/Table' import { Tooltip } from 'app/components/Tooltip' +import { IdPrefix } from 'app/constants/idPrefixes' import { methodLabels, methodTooltipLabels, @@ -55,6 +57,7 @@ const LOADING_ANNOTATIONS = range(0, MAX_PER_PAGE).map(() => ({ https_path: '', s3_path: '', shape_type: '', + fileId: 0, })) function ConfidenceValue({ value }: { value: number }) { @@ -139,47 +142,64 @@ export function AnnotationTable() { columnHelper.accessor('id', { header: () => ( - {t('annotationId')} + {t('annotationName')} ), cell: ({ row: { original: annotation } }) => ( ( +
+ + + +
+ )} width={AnnotationTableWidths.id} > -
+

- {annotation.id} + {annotation.fileId} + {annotation.object_name}

- {annotation.ground_truth_status && ( - } - placement="top" - > -
+

+ + {t('annotationId')}: {IdPrefix.Annotation}- + + + {annotation.id} + +

+ + {annotation.ground_truth_status && ( + } + placement="top" > - {t('groundTruth')} -
-
- )} +
+ {t('groundTruth')} +
+ + )} +
-
+
@@ -326,6 +346,7 @@ export function AnnotationTable() { referenceTomogramId: tomograms[0]?.id, // TODO(bchu): is_portal_standard objectShapeType: annotation.shape_type, fileFormat: annotation.format, + annotationName: `${annotation.fileId} ${annotation.object_name}`, }) } startIcon={ @@ -356,8 +377,13 @@ export function AnnotationTable() { const annotations = useMemo( () => annotationFiles.map((annotationFile) => { - const { annotation: _, ...restAnnotationFileFields } = annotationFile + const { + annotation: _, + id, + ...restAnnotationFileFields + } = annotationFile return { + fileId: id, ...restAnnotationFileFields, ...annotationFile.annotation, } as AnnotationRow diff --git a/frontend/packages/data-portal/app/constants/query.ts b/frontend/packages/data-portal/app/constants/query.ts index b8ffa2976..ad83e9d0d 100644 --- a/frontend/packages/data-portal/app/constants/query.ts +++ b/frontend/packages/data-portal/app/constants/query.ts @@ -1,5 +1,6 @@ export enum QueryParams { AnnotationId = 'annotation_id', + AnnotationName = 'annotation_name', AnnotationSoftware = 'annotation-software', AnnotationsPage = 'annotations-page', AuthorName = 'author', diff --git a/frontend/packages/data-portal/app/graphql/getRunById.server.ts b/frontend/packages/data-portal/app/graphql/getRunById.server.ts index 029fe8756..05d16691d 100644 --- a/frontend/packages/data-portal/app/graphql/getRunById.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunById.server.ts @@ -186,6 +186,7 @@ const GET_RUN_BY_ID_QUERY = gql(` limit: $limit offset: $annotationsOffset ) { + id shape_type format diff --git a/frontend/packages/data-portal/app/hooks/useDownloadModalQueryParamState.ts b/frontend/packages/data-portal/app/hooks/useDownloadModalQueryParamState.ts index db921902d..8517a9c21 100644 --- a/frontend/packages/data-portal/app/hooks/useDownloadModalQueryParamState.ts +++ b/frontend/packages/data-portal/app/hooks/useDownloadModalQueryParamState.ts @@ -37,6 +37,10 @@ export function useDownloadModalQueryParamState() { QueryParams.AnnotationId, ) + const [annotationName, setAnnotationName] = useQueryParam( + QueryParams.AnnotationName, + ) + const [tomogramId, setTomogramId] = useQueryParam( QueryParams.DownloadTomogramId, ) @@ -64,6 +68,7 @@ export function useDownloadModalQueryParamState() { [QueryParams.ReferenceTomogramId]: stringParam(), [QueryParams.ObjectShapeType]: stringParam(), [QueryParams.FileFormat]: stringParam(), + [QueryParams.AnnotationName]: stringParam(), }) const getPlausiblePayload = useCallback( @@ -152,6 +157,7 @@ export function useDownloadModalQueryParamState() { [QueryParams.ReferenceTomogramId]: String(payload.referenceTomogramId), [QueryParams.ObjectShapeType]: payload.objectShapeType, [QueryParams.FileFormat]: payload.fileFormat, + [QueryParams.AnnotationName]: payload.annotationName, }) }, [getPlausiblePayload, plausible, setDownloadParams], @@ -283,5 +289,7 @@ export function useDownloadModalQueryParamState() { setTomogramSampling, tomogramProcessing, tomogramSampling, + annotationName, + setAnnotationName, } } diff --git a/frontend/packages/data-portal/app/hooks/usePlausible.ts b/frontend/packages/data-portal/app/hooks/usePlausible.ts index d5ab1fc97..5512e5f85 100644 --- a/frontend/packages/data-portal/app/hooks/usePlausible.ts +++ b/frontend/packages/data-portal/app/hooks/usePlausible.ts @@ -28,6 +28,7 @@ export enum Events { export type PlausibleDownloadModalPayload = T & { annotationId?: number + annotationName?: string tomogramId?: number referenceTomogramId?: number config?: DownloadConfig diff --git a/frontend/packages/data-portal/app/state/annotation.ts b/frontend/packages/data-portal/app/state/annotation.ts index 0639a5a88..5db110831 100644 --- a/frontend/packages/data-portal/app/state/annotation.ts +++ b/frontend/packages/data-portal/app/state/annotation.ts @@ -8,7 +8,10 @@ export type BaseAnnotation = export type AnnotationFile = GetRunByIdQuery['annotation_files'][number] -export type AnnotationRow = BaseAnnotation & Omit +export type AnnotationRow = BaseAnnotation & + Omit & { + fileId: number + } const activeAnnotationAtom = atom(null) diff --git a/frontend/packages/data-portal/public/locales/en/translation.json b/frontend/packages/data-portal/public/locales/en/translation.json index 42d9aa2f3..7e1b0317e 100644 --- a/frontend/packages/data-portal/public/locales/en/translation.json +++ b/frontend/packages/data-portal/public/locales/en/translation.json @@ -30,14 +30,15 @@ "annotationConfidence": "Annotation Confidence", "annotationDetails": "Annotation Details", "annotationId": "Annotation ID", - "annotationsMayRequireTransformation": "Annotations may require transformation if the desired tomogram has a different Alignment ID.", "annotationMetadata": "Annotation Metadata", "annotationMethod": "Annotation Method", "annotationMethodsSummary": "Annotation Methods Summary", + "annotationName": "Annotation Name", "annotationObject": "Annotation Object", "annotationOverview": "Annotation Overview", "annotationSoftware": "Annotation Software", "annotations": "Annotations", + "annotationsMayRequireTransformation": "Annotations may require transformation if the desired tomogram has a different Alignment ID.", "annotationsSummary": "Annotations Summary", "annotationsTotal": "Annotations (Total)", "api": "API", @@ -48,10 +49,10 @@ "authorName": "Author Name", "authorNameLegend": "Author Name Legend", "authorOrcid": "Author ORCID", - "authors": "Authors", - "authorsMaybePlural": "Author(s)", "authorSubmitted": "Author Submitted", "authorSubmittedTooltip": "Author Submitted: Tomogram contributed by the dataset author.", + "authors": "Authors", + "authorsMaybePlural": "Author(s)", "automated": "Automated", "available": "Available", "availableFiles": "Available Files", @@ -105,7 +106,6 @@ "dataSummary": "Data Summary", "dataset": "Dataset", "datasetAuthor": "Dataset Author", - "datasetsDescription": "Datasets are contributed sets of files associated with imaging one sample type with the same experimental conditions.", "datasetDetails": "Dataset Details", "datasetId": "Dataset ID", "datasetIds": "Dataset IDs", @@ -114,18 +114,19 @@ "datasetOverview": "Dataset Overview", "datasetTitle": "Dataset Title", "datasets": "Datasets", + "datasetsDescription": "Datasets are contributed sets of files associated with imaging one sample type with the same experimental conditions.", "datasetsTab": "Datasets {{count}}", "deposition": "Deposition", "depositionAnnotationsOnly": "Deposition annotations only", "depositionData": "Datasets with Deposition Data", "depositionDate": "Deposition Date", - "depositionsDescription": "Depositions are collections of datasets, annotations, and/or (in the future) tomograms contributed by the same author(s). The website currently shows only depositions that include annotations.", "depositionDetails": "Deposition Details", "depositionId": "Deposition ID", "depositionName": "Deposition Name", "depositionOnly": "Deposition only", "depositionOverview": "Deposition Overview", "depositions": "Depositions", + "depositionsDescription": "Depositions are collections of datasets, annotations, and/or (in the future) tomograms contributed by the same author(s). The website currently shows only depositions that include annotations.", "depositionsTab": "Depositions {{count}}", "description": "Description", "developAMLModel": "Develop a ML model for annotating subcellular structures and proteins in CryoET data", @@ -244,10 +245,10 @@ "next": "Next", "no": "No", "noAnnotationsAvailable": "No Annotations Available", - "normalText": "Normal text", - "notApplicable": "Not Applicable", "noTomogramAvailable": "No tomogram available", "noTomogramsAvailable": "No tomograms available", + "normalText": "Normal text", + "notApplicable": "Not Applicable", "notSubmitted": "Not Submitted", "numberOfAnnotations": "Number of Annotations", "numberOfRuns": "Number of Runs",