Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: address misc UI/UX bugs #1192

Merged
merged 6 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,12 @@ export function DepositionTable() {
<ul className="list-none flex flex-col gap-sds-xs">
{Object.entries(shapeTypeToI18nKey)
.filter(([key]) => shapeTypes.includes(key))
.map((entry) => (
.map(([k, v]) => (
<li
className="whitespace-nowrap overflow-x-hidden overflow-ellipsis"
key={entry[0]}
key={k}
>
{t(entry[1])}
{t(v)}
</li>
))}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,13 @@ export function MethodLinksMetadataTable({
.map((methodData, i) => (
<div className="flex flex-col gap-sds-xl">
<MethodSummarySection
label={t('methodCount', {
value: startCase(converter.toWords(i + 1)),
})}
label={
deposition.annotation_methods.length === 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - comment why 1 is the only value that's ignored

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

design wants if theres only one method for there not to be a "Method One" so we only ignore 1; if there's 0 it wont be executed at all and otherwise all values should display the header

? undefined
: t('methodCount', {
value: startCase(converter.toWords(i + 1)),
})
}
data={methodData as MethodDataType}
annotationsCount={
annotationMethodCounts.get(methodData.annotation_method) ?? 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { useMemo } from 'react'

import { shapeTypeToI18nKey } from 'app/constants/objectShapeTypes'
import { QueryParams } from 'app/constants/query'
import { useFilter } from 'app/hooks/useFilter'
import { useI18n } from 'app/hooks/useI18n'
import { BaseFilterOption } from 'app/types/filter'
import { ObjectShapeType } from 'app/types/shapeTypes'

import { SelectFilter } from './SelectFilter'

function getObjectShapeTypeOptions(
objectShapeTypes: string[],
t: ReturnType<typeof useI18n>['t'],
): BaseFilterOption[] {
return objectShapeTypes.map((value) => ({ value }))
return objectShapeTypes.map((value) => ({
label: t(shapeTypeToI18nKey[value as ObjectShapeType]),
value,
}))
}

export function AnnotatedObjectShapeTypeFilter({
Expand All @@ -26,13 +32,13 @@ export function AnnotatedObjectShapeTypeFilter({
} = useFilter()

const objectShapeTypeOptions = useMemo(
() => getObjectShapeTypeOptions(allObjectShapeTypes),
[allObjectShapeTypes],
() => getObjectShapeTypeOptions(allObjectShapeTypes, t),
[allObjectShapeTypes, t],
)

const objectShapeTypeValue = useMemo(
() => getObjectShapeTypeOptions(objectShapeTypes),
[objectShapeTypes],
() => getObjectShapeTypeOptions(objectShapeTypes, t),
[objectShapeTypes, t],
)

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { AccordionMetadataTable } from 'app/components/AccordionMetadataTable'
import { shapeTypeToI18nKey } from 'app/constants/objectShapeTypes'
import { useI18n } from 'app/hooks/useI18n'
import { useAnnotation } from 'app/state/annotation'
import { ObjectShapeType } from 'app/types/shapeTypes'
import { getTableData } from 'app/utils/table'

import { ObjectIdLink } from './components/ObjectIdLink'
Expand Down Expand Up @@ -31,7 +33,7 @@ export function AnnotationObjectTable() {
},
{
label: t('objectShapeType'),
values: [annotation.shape_type],
values: [t(shapeTypeToI18nKey[annotation.shape_type as ObjectShapeType])],
},
{
label: t('objectState'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
methodTooltipLabels,
MethodType,
} from 'app/constants/methodTypes'
import { shapeTypeToI18nKey } from 'app/constants/objectShapeTypes'
import { MAX_PER_PAGE } from 'app/constants/pagination'
import { QueryParams } from 'app/constants/query'
import { AnnotationTableWidths } from 'app/constants/table'
Expand All @@ -34,6 +35,7 @@ import {
import { useRunById } from 'app/hooks/useRunById'
import { AnnotationRow, useAnnotation } from 'app/state/annotation'
import { I18nKeys } from 'app/types/i18n'
import { ObjectShapeType } from 'app/types/shapeTypes'
import { DASHED_BORDERED_CLASSES } from 'app/utils/classNames'
import { cns, cnsNoMerge } from 'app/utils/cns'

Expand Down Expand Up @@ -228,7 +230,7 @@ export function AnnotationTable() {

cell: ({ getValue }) => (
<TableCell width={AnnotationTableWidths.files}>
{getValue()}
{t(shapeTypeToI18nKey[getValue() as ObjectShapeType])}
</TableCell>
),
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { ObjectShapeType } from 'app/types/shapeTypes'

type ShapeTypeToI18nKeyMap = { [key in ObjectShapeType]: I18nKeys }

export const shapeTypeToI18nKey: ShapeTypeToI18nKeyMap = {
export const shapeTypeToI18nKey = {
InstanceSegmentation: 'instanceSegmentation',
OrientedPoint: 'orientedPoint',
Point: 'point',
SegmentationMask: 'segmentationMask',
}
} as const satisfies ShapeTypeToI18nKeyMap

export const shapeTypeToI18nKeyPlural: ShapeTypeToI18nKeyMap = {
export const shapeTypeToI18nKeyPlural = {
InstanceSegmentation: 'instanceSegmentations',
OrientedPoint: 'orientedPoints',
Point: 'points',
SegmentationMask: 'segmentationMasks',
}
} as const satisfies ShapeTypeToI18nKeyMap
Original file line number Diff line number Diff line change
@@ -1,51 +1,72 @@
import type { ApolloClient, NormalizedCacheObject } from '@apollo/client'

import { gql } from 'app/__generated__'
import { Datasets_Bool_Exp } from 'app/__generated__/graphql'

const GET_DATASETS_FILTER_DATA_QUERY = gql(`
query GetDatasetsFilterData(
$filter: datasets_bool_exp,
$datasets_filter: datasets_bool_exp,
$tiltseries_filter: tiltseries_bool_exp,
$tomograms_filter: tomograms_bool_exp,
$annotations_filter: annotations_bool_exp,
$annotation_files_filter: annotation_files_bool_exp,
) {
organism_names: datasets(where: $filter, distinct_on: organism_name) {
organism_names: datasets(where: $datasets_filter, distinct_on: organism_name) {
organism_name
}

camera_manufacturers: tiltseries(distinct_on: camera_manufacturer) {
camera_manufacturers: tiltseries(where: $tiltseries_filter, distinct_on: camera_manufacturer) {
camera_manufacturer
}

reconstruction_methods: tomograms(distinct_on: reconstruction_method) {
reconstruction_methods: tomograms(where: $tomograms_filter, distinct_on: reconstruction_method) {
reconstruction_method
}

reconstruction_softwares: tomograms(distinct_on: reconstruction_software) {
reconstruction_softwares: tomograms(where: $tomograms_filter, distinct_on: reconstruction_software) {
reconstruction_software
}

object_names: annotations(distinct_on: object_name) {
object_names: annotations(where: $annotations_filter, distinct_on: object_name) {
object_name
}

object_shape_types: annotation_files(distinct_on: shape_type) {
object_shape_types: annotation_files(where: $annotation_files_filter, distinct_on: shape_type) {
shape_type
}
}
`)

export async function getDatasetsFilterData({
client,
filter = {},
depositionId,
}: {
client: ApolloClient<NormalizedCacheObject>
filter: Datasets_Bool_Exp
depositionId?: number
}) {
const start = performance.now()

const filter = {
deposition_id: {
_eq: depositionId,
},
}

const results = await client.query({
query: GET_DATASETS_FILTER_DATA_QUERY,
variables: {
filter,
datasets_filter: depositionId
? {
runs: {
tomogram_voxel_spacings: {
annotations: filter,
},
},
}
: {},
tiltseries_filter: depositionId ? filter : {},
tomograms_filter: depositionId ? filter : {},
annotations_filter: depositionId ? filter : {},
annotation_files_filter: depositionId ? { annotation: filter } : {},
},
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ const GET_DEPOSITION_BY_ID = gql(`
annotation_software
method_links
method_type

}

annotations_aggregate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
client: apolloClient,
params: url.searchParams,
}),
getDatasetsFilterData({ client: apolloClient, filter: {} }),
getDatasetsFilterData({ client: apolloClient }),
])

return json({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export async function loader({ request }: LoaderFunctionArgs) {
}

export default function BrowseDepositionsPage() {
// TODO: hook up to backend when available
const { depositionCount, filteredDepositionCount } = useDepositions()
const { reset } = useFilter()
const { t } = useI18n()
Expand Down
12 changes: 1 addition & 11 deletions frontend/packages/data-portal/app/routes/depositions.$id.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,7 @@ export async function loader({ params, request }: LoaderFunctionArgs) {
}),
getDatasetsFilterData({
client: apolloClient,
filter: {
runs: {
tomogram_voxel_spacings: {
annotations: {
deposition_id: {
_eq: id,
},
},
},
},
},
depositionId: id,
}),
])

Expand Down
2 changes: 1 addition & 1 deletion frontend/packages/data-portal/app/utils/featureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type FeatureFlagEnvironment = typeof process.env.ENV
export type FeatureFlagKey = 'depositions' | 'multipleTomograms'

export const FEATURE_FLAGS: Record<FeatureFlagKey, FeatureFlagEnvironment[]> = {
depositions: ['local', 'dev'],
depositions: ['local', 'dev', 'staging', 'prod'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

multipleTomograms: ['local', 'dev'],
}

Expand Down
53 changes: 28 additions & 25 deletions frontend/packages/data-portal/e2e/browseDatasetFilters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import { FiltersPage } from 'e2e/pageObjects/filters/filtersPage'
import { serializeAvailableFiles } from 'e2e/pageObjects/filters/utils'

import { QueryParams } from 'app/constants/query'
import { ObjectShapeType } from 'app/types/shapeTypes'
import { getPrefixedId } from 'app/utils/idPrefixes'

import { getApolloClient } from './apollo'
import { BROWSE_DATASETS_URL, E2E_CONFIG, translations } from './constants'
import { onlyRunIfEnabled } from './utils'
import { getObjectShapeTypeLabel, onlyRunIfEnabled } from './utils'

test.describe('Browse datasets page filters', () => {
let client: ApolloClient<NormalizedCacheObject>
Expand Down Expand Up @@ -1156,17 +1157,16 @@ test.describe('Browse datasets page filters', () => {
getPrefixedId(E2E_CONFIG.depositionId, QueryParams.DepositionId),
)

// TODO: (kne42) uncomment when hooked up to backend
// await filtersActor.expectDataAndDatasetsTableToMatch({
// client,
// url: BROWSE_DATASETS_URL,
// queryParamsList: [
// {
// queryParamKey: QueryParams.DepositionId,
// queryParamValue: E2E_CONFIG.depositionId,
// },
// ],
// })
await filtersActor.expectDataAndDatasetsTableToMatch({
client,
url: BROWSE_DATASETS_URL,
queryParamsList: [
{
queryParamKey: QueryParams.DepositionId,
queryParamValue: E2E_CONFIG.depositionId,
},
],
})
})
test('should filter when opening URL', async () => {
await filtersActor.goToFilteredUrl({
Expand All @@ -1183,17 +1183,16 @@ test.describe('Browse datasets page filters', () => {
getPrefixedId(E2E_CONFIG.depositionId, QueryParams.DepositionId),
)

// TODO: (kne42) uncomment when hooked up to backend
// await filtersActor.expectDataAndDatasetsTableToMatch({
// client,
// url: BROWSE_DATASETS_URL,
// queryParamsList: [
// {
// queryParamKey: QueryParams.DepositionId,
// queryParamValue: E2E_CONFIG.depositionId,
// },
// ],
// })
await filtersActor.expectDataAndDatasetsTableToMatch({
client,
url: BROWSE_DATASETS_URL,
queryParamsList: [
{
queryParamKey: QueryParams.DepositionId,
queryParamValue: E2E_CONFIG.depositionId,
},
],
})
})
test('should disable filter when deselecting', async () => {
await filtersActor.goToFilteredUrl({
Expand Down Expand Up @@ -2485,7 +2484,9 @@ test.describe('Browse datasets page filters', () => {

await filtersActor.addSingleSelectFilter({
label: translations.objectShapeType,
value: E2E_CONFIG.objectShapeType,
value: getObjectShapeTypeLabel(
E2E_CONFIG.objectShapeType as ObjectShapeType,
),
})

await filtersActor.expectUrlQueryParamsToBeCorrect({
Expand Down Expand Up @@ -2542,7 +2543,9 @@ test.describe('Browse datasets page filters', () => {
],
})

await filtersPage.removeFilterOption(E2E_CONFIG.objectShapeType)
await filtersPage.removeFilterOption(
getObjectShapeTypeLabel(E2E_CONFIG.objectShapeType as ObjectShapeType),
)

await filtersActor.expectUrlQueryParamsToBeCorrect({
url: BROWSE_DATASETS_URL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,6 @@ export class FiltersActor {
}) {
const { data: datasetsFilterData } = await getDatasetsFilterData({
client,
filter: {},
})

const organismNames = getFilteredOrganismNamesFromData({
Expand Down
Loading
Loading