From 45e214e1b02970edf795de5392709e0be23f959c Mon Sep 17 00:00:00 2001 From: Jeremy Asuncion Date: Fri, 13 Dec 2024 16:41:59 -0800 Subject: [PATCH 01/35] test: simple component unit tests (#1392) #1374 - Unit tests for simple components - Upgrade Remix to fix some type errors with tests - I was unable to separate the upgrade into a separate PR due to an error related to the the local eslint plugin package - It should be safe to have the upgrade included in this PR as long as the E2Es pass --- .../app/components/Accordion.test.tsx | 39 ++ .../components/AnnotatedObjectsList.test.tsx | 26 ++ .../app/components/AnnotatedObjectsList.tsx | 8 +- .../app/components/Breadcrumbs.test.tsx | 205 +++++++++++ .../app/components/Breadcrumbs.tsx | 12 +- .../app/components/CollapsibleList.test.tsx | 89 +++++ .../app/components/CollapsibleList.tsx | 4 +- .../app/components/CopyBox.test.tsx | 32 ++ .../app/components/DatabaseEntry.test.tsx | 80 ++++ .../app/components/DatabaseEntry.tsx | 2 +- .../app/components/DepositionFilterBanner.tsx | 5 +- .../app/components/Drawer.test.tsx | 46 +++ .../data-portal/app/components/Drawer.tsx | 9 +- .../app/components/Filters/SelectFilter.tsx | 8 +- .../app/components/HeaderKeyPhoto.test.tsx | 35 ++ .../app/components/HydrateAtomsProvider.tsx | 36 ++ .../app/components/InlineMetadata.test.tsx | 32 ++ .../app/components/KeyPhoto.test.tsx | 19 + .../app/components/MenuDropdown.test.tsx | 28 ++ .../app/components/NoFilteredResults.test.tsx | 52 +++ .../app/components/Select.test.tsx | 121 ++++++ .../data-portal/app/components/Select.tsx | 32 +- .../app/components/TomogramTypeBadge.test.tsx | 26 ++ .../app/components/TomogramTypeBadge.tsx | 1 + .../data-portal/app/hooks/useRunById.ts | 4 +- .../data-portal/app/state/filterHistory.ts | 8 +- .../packages/data-portal/app/types/state.ts | 12 + .../data-portal/app/utils/nullish.test.ts | 15 + .../packages/data-portal/app/utils/nullish.ts | 2 +- .../data-portal/app/utils/proxy.test.ts | 44 --- .../packages/data-portal/app/utils/proxy.ts | 54 --- .../packages/data-portal/app/utils/table.ts | 4 +- frontend/packages/data-portal/e2e/apollo.ts | 6 + frontend/packages/data-portal/jest.config.cjs | 2 +- frontend/packages/data-portal/package.json | 19 +- .../public/locales/en/translation.json | 13 +- frontend/packages/data-portal/setupTests.ts | 20 + frontend/packages/eslint-config/package.json | 2 +- frontend/pnpm-lock.yaml | 348 +++++++----------- 39 files changed, 1138 insertions(+), 362 deletions(-) create mode 100644 frontend/packages/data-portal/app/components/Accordion.test.tsx create mode 100644 frontend/packages/data-portal/app/components/AnnotatedObjectsList.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Breadcrumbs.test.tsx create mode 100644 frontend/packages/data-portal/app/components/CollapsibleList.test.tsx create mode 100644 frontend/packages/data-portal/app/components/CopyBox.test.tsx create mode 100644 frontend/packages/data-portal/app/components/DatabaseEntry.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Drawer.test.tsx create mode 100644 frontend/packages/data-portal/app/components/HeaderKeyPhoto.test.tsx create mode 100644 frontend/packages/data-portal/app/components/HydrateAtomsProvider.tsx create mode 100644 frontend/packages/data-portal/app/components/InlineMetadata.test.tsx create mode 100644 frontend/packages/data-portal/app/components/KeyPhoto.test.tsx create mode 100644 frontend/packages/data-portal/app/components/MenuDropdown.test.tsx create mode 100644 frontend/packages/data-portal/app/components/NoFilteredResults.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Select.test.tsx create mode 100644 frontend/packages/data-portal/app/components/TomogramTypeBadge.test.tsx create mode 100644 frontend/packages/data-portal/app/types/state.ts create mode 100644 frontend/packages/data-portal/app/utils/nullish.test.ts delete mode 100644 frontend/packages/data-portal/app/utils/proxy.test.ts delete mode 100644 frontend/packages/data-portal/app/utils/proxy.ts create mode 100644 frontend/packages/data-portal/setupTests.ts diff --git a/frontend/packages/data-portal/app/components/Accordion.test.tsx b/frontend/packages/data-portal/app/components/Accordion.test.tsx new file mode 100644 index 000000000..80f46ed50 --- /dev/null +++ b/frontend/packages/data-portal/app/components/Accordion.test.tsx @@ -0,0 +1,39 @@ +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { Accordion } from './Accordion' + +const CHILDREN_TEXT = 'Children' + +function renderAccordion(initialOpen = false) { + render( + Header

} initialOpen={initialOpen}> + {CHILDREN_TEXT} +
, + ) +} + +describe('', () => { + it('should render closed', () => { + renderAccordion() + expect(screen.queryByText(CHILDREN_TEXT)).not.toBeVisible() + }) + + it('should open on click', async () => { + renderAccordion() + await userEvent.click(screen.getByRole('button')) + expect(screen.queryByText(CHILDREN_TEXT)).toBeVisible() + }) + + it('should close on click', async () => { + renderAccordion() + await userEvent.click(screen.getByRole('button')) + await userEvent.click(screen.getByRole('button')) + expect(screen.queryByText(CHILDREN_TEXT)).not.toBeVisible() + }) + + it('should render opened if initialOpen === true', () => { + renderAccordion(true) + expect(screen.queryByText(CHILDREN_TEXT)).toBeVisible() + }) +}) diff --git a/frontend/packages/data-portal/app/components/AnnotatedObjectsList.test.tsx b/frontend/packages/data-portal/app/components/AnnotatedObjectsList.test.tsx new file mode 100644 index 000000000..e942df567 --- /dev/null +++ b/frontend/packages/data-portal/app/components/AnnotatedObjectsList.test.tsx @@ -0,0 +1,26 @@ +import { render, screen } from '@testing-library/react' + +import { ANNOTATED_OBJECTS_MAX } from 'app/constants/pagination' + +import { AnnotatedObjectsList } from './AnnotatedObjectsList' + +function getItems(length: number) { + return Array(length) + .fill(null) + .map((_, idx) => `test ${idx}`) +} + +describe('', () => { + it('should render annotated objects', () => { + const items = getItems(ANNOTATED_OBJECTS_MAX) + render() + items.forEach((item) => expect(screen.getByText(item)).toBeVisible()) + }) + + it('should render n more objects if list is greater than max', () => { + const nMoreItems = 3 + const items = getItems(ANNOTATED_OBJECTS_MAX + nMoreItems) + render() + expect(screen.queryByText('nMoreObjects')).toBeVisible() + }) +}) diff --git a/frontend/packages/data-portal/app/components/AnnotatedObjectsList.tsx b/frontend/packages/data-portal/app/components/AnnotatedObjectsList.tsx index 85a9864a9..25069a976 100644 --- a/frontend/packages/data-portal/app/components/AnnotatedObjectsList.tsx +++ b/frontend/packages/data-portal/app/components/AnnotatedObjectsList.tsx @@ -4,7 +4,7 @@ import { range } from 'lodash-es' import { ReactNode } from 'react' import { ANNOTATED_OBJECTS_MAX } from 'app/constants/pagination' -import { i18n } from 'app/i18n' +import { useI18n } from 'app/hooks/useI18n' import { cns } from 'app/utils/cns' import { Tooltip } from './Tooltip' @@ -30,6 +30,8 @@ export function AnnotatedObjectsList({ annotatedObjects: string[] isLoading?: boolean }) { + const { t } = useI18n() + if (annotatedObjects.length === 0) { return null } @@ -76,7 +78,9 @@ export function AnnotatedObjectsList({ 'rounded-sds-m py-sds-xxxs px-sds-xs inline', )} > - {i18n.nMoreObjects(nodes.length + 1 - ANNOTATED_OBJECTS_MAX)} + {t('nMoreObjects', { + count: nodes.length + 1 - ANNOTATED_OBJECTS_MAX, + })} diff --git a/frontend/packages/data-portal/app/components/Breadcrumbs.test.tsx b/frontend/packages/data-portal/app/components/Breadcrumbs.test.tsx new file mode 100644 index 000000000..d76e168fd --- /dev/null +++ b/frontend/packages/data-portal/app/components/Breadcrumbs.test.tsx @@ -0,0 +1,205 @@ +import { createRemixStub } from '@remix-run/testing' +import { render, screen } from '@testing-library/react' +import { ComponentProps } from 'react' + +import { + previousBrowseDatasetParamsAtom, + previousDepositionIdAtom, + previousSingleDatasetParamsAtom, + previousSingleDepositionParamsAtom, +} from 'app/state/filterHistory' +import { AtomTupleWithValue } from 'app/types/state' + +import { Breadcrumbs } from './Breadcrumbs' +import { HydrateAtomsProvider } from './HydrateAtomsProvider' + +const BREADCRUMB_DATA = { + id: 10, + title: 'Title', +} + +type BreadcrumbsProp = ComponentProps + +function renderBreadcrumbs({ + previousBrowseDatasetParams, + previousDepositionId, + previousSingleDatasetParams, + previousSingleDepositionParams, + variant, +}: { + previousBrowseDatasetParams?: string + previousDepositionId?: number + previousSingleDatasetParams?: string + previousSingleDepositionParams?: string + variant: BreadcrumbsProp['variant'] +}) { + function BreadcrumbWrapper() { + const initialValues: AtomTupleWithValue[] = [] + + if (previousBrowseDatasetParams) { + initialValues.push([ + previousBrowseDatasetParamsAtom, + previousBrowseDatasetParams, + ]) + } + + if (previousDepositionId) { + initialValues.push([previousDepositionIdAtom, previousDepositionId]) + } + + if (previousSingleDatasetParams) { + initialValues.push([ + previousSingleDatasetParamsAtom, + previousSingleDatasetParams, + ]) + } + + if (previousSingleDepositionParams) { + initialValues.push([ + previousSingleDepositionParamsAtom, + previousSingleDepositionParams, + ]) + } + + return ( + + + + ) + } + + const BreadcrumbsStub = createRemixStub([ + { + path: '/', + Component: BreadcrumbWrapper, + }, + ]) + + render() +} + +const BROWSE_DATASETS_URL = '/browse-data/datasets' +const BROWSE_DEPOSITIONS_URL = '/browse-data/depositions' +const SINGLE_DATASET_URL = `/datasets/${BREADCRUMB_DATA.id}` +const SINGLE_DATASET_TITLE = `dataset: ${BREADCRUMB_DATA.title}` + +function testReturnToDepositionLink() { + it('should show return to deposition link', () => { + const params = 'object=foo' + const id = 10 + + renderBreadcrumbs({ + variant: 'dataset', + previousDepositionId: id, + previousSingleDepositionParams: params, + }) + + expect( + screen.queryByRole('link', { name: 'returnToDeposition' }), + ).toHaveAttribute('href', `/depositions/${id}?${params}`) + }) +} + +describe('', () => { + describe('variant=dataset', () => { + it('should render browse all datasets link', () => { + renderBreadcrumbs({ variant: 'dataset' }) + + expect( + screen.queryByRole('link', { name: 'allDatasets' }), + ).toHaveAttribute('href', BROWSE_DATASETS_URL) + }) + + it('should render dataset breadcrumb', () => { + renderBreadcrumbs({ variant: 'dataset' }) + + expect(screen.queryByText('dataset')).toBeVisible() + }) + + it('should carry over query params', () => { + const params = 'object=foo' + + renderBreadcrumbs({ + variant: 'dataset', + previousBrowseDatasetParams: params, + }) + + expect( + screen.queryByRole('link', { name: 'allDatasets' }), + ).toHaveAttribute('href', `${BROWSE_DATASETS_URL}?${params}`) + }) + + testReturnToDepositionLink() + }) + + describe('variant=run', () => { + it('should render browse all datasets link', () => { + renderBreadcrumbs({ variant: 'run' }) + + expect( + screen.queryByRole('link', { name: 'allDatasets' }), + ).toHaveAttribute('href', BROWSE_DATASETS_URL) + }) + + it('should render run breadcrumb', () => { + renderBreadcrumbs({ variant: 'run' }) + + expect(screen.queryByText('run')).toBeVisible() + }) + + it('should render dataset link', () => { + renderBreadcrumbs({ variant: 'run' }) + + expect( + screen.queryByRole('link', { + name: SINGLE_DATASET_TITLE, + }), + ).toHaveAttribute('href', SINGLE_DATASET_URL) + }) + + it('should carry over query params', () => { + const previousBrowseDatasetParams = 'object=foo' + const previousSingleDatasetParams = 'tilt_min=90' + + renderBreadcrumbs({ + variant: 'run', + previousBrowseDatasetParams, + previousSingleDatasetParams, + }) + + expect( + screen.queryByRole('link', { name: 'allDatasets' }), + ).toHaveAttribute( + 'href', + `${BROWSE_DATASETS_URL}?${previousBrowseDatasetParams}`, + ) + + expect( + screen.queryByRole('link', { + name: SINGLE_DATASET_TITLE, + }), + ).toHaveAttribute( + 'href', + `${SINGLE_DATASET_URL}?${previousSingleDatasetParams}`, + ) + }) + + testReturnToDepositionLink() + }) + + describe('variant=deposition', () => { + it('should render browse all depositions link', () => { + renderBreadcrumbs({ variant: 'deposition' }) + + expect( + screen.queryByRole('link', { name: 'allDepositions' }), + ).toHaveAttribute('href', BROWSE_DEPOSITIONS_URL) + }) + + it('should render deposition breadcrumb', () => { + renderBreadcrumbs({ variant: 'deposition' }) + + expect(screen.queryByText('deposition')).toBeVisible() + }) + }) +}) diff --git a/frontend/packages/data-portal/app/components/Breadcrumbs.tsx b/frontend/packages/data-portal/app/components/Breadcrumbs.tsx index 18ad58cf3..466aab598 100644 --- a/frontend/packages/data-portal/app/components/Breadcrumbs.tsx +++ b/frontend/packages/data-portal/app/components/Breadcrumbs.tsx @@ -70,7 +70,11 @@ export function Breadcrumbs({ const params = variant === 'deposition' ? undefined : previousBrowseDatasetParams - return `${url}?${params}` + if (params) { + return `${url}?${params}` + } + + return url }, [previousBrowseDatasetParams, variant]) const singleDatasetLink = useMemo(() => { @@ -80,7 +84,11 @@ export function Breadcrumbs({ const url = `/datasets/${data.id}` - return `${url}?${previousSingleDatasetParams}` + if (previousSingleDatasetParams) { + return `${url}?${previousSingleDatasetParams}` + } + + return url }, [variant, data.id, previousSingleDatasetParams]) const returnToDepositionLink = diff --git a/frontend/packages/data-portal/app/components/CollapsibleList.test.tsx b/frontend/packages/data-portal/app/components/CollapsibleList.test.tsx new file mode 100644 index 000000000..2c19e9041 --- /dev/null +++ b/frontend/packages/data-portal/app/components/CollapsibleList.test.tsx @@ -0,0 +1,89 @@ +/* eslint-disable jest/no-conditional-expect */ + +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { CollapsibleList, CollapsibleListEntry } from './CollapsibleList' + +const ENTRIES: CollapsibleListEntry[] = [ + { + key: '1', + entry: 'Foo', + }, + { + key: '2', + entry: 'Bar', + }, + { + key: '3', + entry: 'FooBar', + }, + { + key: '4', + entry: 'BarFoo', + }, +] + +describe('', () => { + it('should render empty state', () => { + render() + + expect(screen.queryByText('notSubmitted')).toBeVisible() + }) + + it('should render all items', () => { + render() + + ENTRIES.forEach(({ entry }) => + expect(screen.queryByText(String(entry))).toBeVisible(), + ) + }) + + it('should render all items if entries is greater than collapseAfter by 1', () => { + render( + , + ) + + ENTRIES.forEach(({ entry }) => + expect(screen.queryByText(String(entry))).toBeVisible(), + ) + }) + + it('should render all items if entries.length < collapseAfter', () => { + render( + , + ) + + ENTRIES.forEach(({ entry }) => + expect(screen.queryByText(String(entry))).toBeVisible(), + ) + }) + + it('should render up to collapseAfter items', () => { + const collapseAfter = 2 + render() + + ENTRIES.slice(0, collapseAfter).forEach(({ entry }, idx) => { + const entryNode = screen.queryByText(String(entry)) + + if (idx < collapseAfter) { + expect(entryNode).toBeVisible() + } else { + expect(entryNode).not.toBeInTheDocument() + } + }) + }) + + it('should render remaining items in collapsible', async () => { + const collapseAfter = 2 + render() + + await userEvent.click(screen.getByRole('button')) + + ENTRIES.slice(collapseAfter).forEach(({ entry }) => { + expect(screen.queryByText(String(entry))).toBeVisible() + }) + + expect(screen.queryByRole('button', { name: 'showLess' })).toBeVisible() + }) +}) diff --git a/frontend/packages/data-portal/app/components/CollapsibleList.tsx b/frontend/packages/data-portal/app/components/CollapsibleList.tsx index 1ed6b0839..c6436b875 100644 --- a/frontend/packages/data-portal/app/components/CollapsibleList.tsx +++ b/frontend/packages/data-portal/app/components/CollapsibleList.tsx @@ -4,13 +4,13 @@ import { ReactNode, useState } from 'react' import { useI18n } from 'app/hooks/useI18n' import { cns } from 'app/utils/cns' -interface ListEntry { +export interface CollapsibleListEntry { key: string entry: ReactNode } export interface CollapsibleListProps { - entries?: ListEntry[] + entries?: CollapsibleListEntry[] // Number of items displayed when collapsed. // Collapse triggers when entries has >= collapseAfter + 2 items, so minimum "Show _ more" value diff --git a/frontend/packages/data-portal/app/components/CopyBox.test.tsx b/frontend/packages/data-portal/app/components/CopyBox.test.tsx new file mode 100644 index 000000000..f83848ac6 --- /dev/null +++ b/frontend/packages/data-portal/app/components/CopyBox.test.tsx @@ -0,0 +1,32 @@ +import { jest } from '@jest/globals' +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { CopyBox } from './CopyBox' + +describe('', () => { + it('should show title if defined', () => { + render() + + expect(screen.queryByText('title:')).toBeVisible() + }) + + it('should copy to clipboard', async () => { + const onCopy = jest.fn() + const writeText = jest.fn() + + Object.assign(navigator, { + clipboard: { + writeText, + }, + }) + + render() + + expect(writeText).not.toHaveBeenCalled() + expect(onCopy).not.toHaveBeenCalled() + await userEvent.click(screen.getByRole('button')) + expect(writeText).toHaveBeenCalled() + expect(onCopy).toHaveBeenCalled() + }) +}) diff --git a/frontend/packages/data-portal/app/components/DatabaseEntry.test.tsx b/frontend/packages/data-portal/app/components/DatabaseEntry.test.tsx new file mode 100644 index 000000000..6a7331481 --- /dev/null +++ b/frontend/packages/data-portal/app/components/DatabaseEntry.test.tsx @@ -0,0 +1,80 @@ +import { createRemixStub } from '@remix-run/testing' +import { render, screen } from '@testing-library/react' + +import { DOI_URL, EMDB_URL, EMPIAR_URL } from 'app/constants/external-dbs' + +import { DatabaseEntry, DatabaseEntryProps } from './DatabaseEntry' + +const TEST_DOI = '10.1234/2022.04.20.488077' + +const TEST_CASES = [ + { + entry: 'EMPIAR-123', + label: 'EMPIAR ID', + id: '123', + url: `${EMPIAR_URL}123`, + }, + { + entry: 'EMD-123', + label: 'EMDB ID', + id: '123', + url: `${EMDB_URL}123`, + }, + { + entry: TEST_DOI, + label: 'DOI', + id: TEST_DOI, + url: `${DOI_URL}${TEST_DOI}`, + }, +] + +function renderDatabaseEntry({ entry, inline }: DatabaseEntryProps) { + function DatabaseEntryWrapper() { + return + } + + const DatasetEntryStub = createRemixStub([ + { + path: '/', + Component: DatabaseEntryWrapper, + }, + ]) + + render() +} + +describe('', () => { + it('should render entry as is if no database type is found', () => { + renderDatabaseEntry({ entry: 'test' }) + + expect(screen.queryByText('test')).toBeVisible() + }) + + TEST_CASES.forEach(({ entry, label, id, url }) => { + const isDOI = entry === TEST_DOI + + it(`should render database type for ${label}`, () => { + renderDatabaseEntry({ entry }) + + expect(screen.queryByText(`${label}:`)).toBeVisible() + + const link = screen.queryByRole('link') + expect(link).toBeVisible() + expect(link).toHaveTextContent(isDOI ? entry : id) + expect(link).toHaveAttribute('href', url) + }) + + it(`should ${isDOI ? 'show' : 'hide'} label for inline ${label}`, () => { + renderDatabaseEntry({ inline: true, entry }) + + // eslint-disable-next-line jest/valid-expect + const matcher = expect(screen.queryByText(`${label}:`)) + + if (isDOI) { + matcher.toBeVisible() + } else { + matcher.not.toBeInTheDocument() + } + }) + }) +}) diff --git a/frontend/packages/data-portal/app/components/DatabaseEntry.tsx b/frontend/packages/data-portal/app/components/DatabaseEntry.tsx index 29d190c13..cb293a539 100644 --- a/frontend/packages/data-portal/app/components/DatabaseEntry.tsx +++ b/frontend/packages/data-portal/app/components/DatabaseEntry.tsx @@ -8,7 +8,7 @@ import { import { TableDataValue } from 'app/types/table' import { cns } from 'app/utils/cns' -interface DatabaseEntryProps { +export interface DatabaseEntryProps { entry: TableDataValue inline?: boolean } diff --git a/frontend/packages/data-portal/app/components/DepositionFilterBanner.tsx b/frontend/packages/data-portal/app/components/DepositionFilterBanner.tsx index 0aa02fec8..725a2fe26 100644 --- a/frontend/packages/data-portal/app/components/DepositionFilterBanner.tsx +++ b/frontend/packages/data-portal/app/components/DepositionFilterBanner.tsx @@ -2,6 +2,7 @@ import { Button, Callout } from '@czi-sds/components' import { I18n } from 'app/components/I18n' import { QueryParams } from 'app/constants/query' +import { useI18n } from 'app/hooks/useI18n' import { useQueryParam } from 'app/hooks/useQueryParam' import { useDepositionHistory, @@ -26,6 +27,8 @@ export function DepositionFilterBanner({ const { previousSingleDepositionParams } = useDepositionHistory() const [, setDepositionId] = useQueryParam(QueryParams.DepositionId) + const { t } = useI18n() + return (
@@ -54,7 +57,7 @@ export function DepositionFilterBanner({ sdsType="secondary" className="shrink-0" > - Remove Filter + {t('removeFilter')}
diff --git a/frontend/packages/data-portal/app/components/Drawer.test.tsx b/frontend/packages/data-portal/app/components/Drawer.test.tsx new file mode 100644 index 000000000..1a5e31b01 --- /dev/null +++ b/frontend/packages/data-portal/app/components/Drawer.test.tsx @@ -0,0 +1,46 @@ +import { jest } from '@jest/globals' +import { PaperProps } from '@mui/material/Paper' +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { Drawer } from './Drawer' + +const onCloseMock = jest.fn() + +function renderDrawer(open = false) { + render( +
+ + +
{children}
} + > +

content

+
+
, + ) +} + +describe('', () => { + it('should hide drawer contents when closed', () => { + renderDrawer() + + expect(screen.queryByText('content')).not.toBeInTheDocument() + }) + + it('should show drawer contents when opened', () => { + renderDrawer(true) + + expect(screen.queryByText('content')).toBeVisible() + }) + + it('should call onClose when clicked outside', async () => { + renderDrawer(true) + + expect(onCloseMock).not.toHaveBeenCalled() + await userEvent.click(screen.getByRole('button', { name: 'some button' })) + expect(onCloseMock).toHaveBeenCalled() + }) +}) diff --git a/frontend/packages/data-portal/app/components/Drawer.tsx b/frontend/packages/data-portal/app/components/Drawer.tsx index bc572a40e..e235ea5aa 100644 --- a/frontend/packages/data-portal/app/components/Drawer.tsx +++ b/frontend/packages/data-portal/app/components/Drawer.tsx @@ -11,11 +11,13 @@ export function Drawer({ className, onClose, open, + PaperComponent = Paper, }: { children: ReactNode className?: string onClose(): void open: boolean + PaperComponent?: typeof Paper }) { const drawerRef = useRef(null) @@ -45,9 +47,12 @@ export function Drawer({ }} transition={{ duration: theme.transitions.duration.complex / 1000 }} > - + {children} - + )} diff --git a/frontend/packages/data-portal/app/components/Filters/SelectFilter.tsx b/frontend/packages/data-portal/app/components/Filters/SelectFilter.tsx index 3ff5cb2bb..155d72a52 100644 --- a/frontend/packages/data-portal/app/components/Filters/SelectFilter.tsx +++ b/frontend/packages/data-portal/app/components/Filters/SelectFilter.tsx @@ -57,11 +57,11 @@ export function SelectFilter< ) const convertSdsOptionToBaseOption = useCallback( - ({ name, ...sdsOption }: DefaultAutocompleteOption) => + (option: string | DefaultAutocompleteOption) => ({ - ...sdsOption, - label: name, - value: labelValueMap[name], + ...(typeof option === 'string' ? {} : option), + label: typeof option === 'string' ? option : option.name, + value: labelValueMap[typeof option === 'string' ? option : option.name], }) as AutocompleteValue, [labelValueMap], ) diff --git a/frontend/packages/data-portal/app/components/HeaderKeyPhoto.test.tsx b/frontend/packages/data-portal/app/components/HeaderKeyPhoto.test.tsx new file mode 100644 index 000000000..5877cd1f5 --- /dev/null +++ b/frontend/packages/data-portal/app/components/HeaderKeyPhoto.test.tsx @@ -0,0 +1,35 @@ +import { createRemixStub } from '@remix-run/testing' +import { render, screen } from '@testing-library/react' + +import { HeaderKeyPhoto } from './HeaderKeyPhoto' + +function renderKeyPhoto(url?: string) { + function HeaderKeyPhotoWrapper() { + return + } + + const HeaderKeyPhotoStub = createRemixStub([ + { + path: '/', + Component: HeaderKeyPhotoWrapper, + }, + ]) + + render() +} + +describe('', () => { + it('should render key photo fallback if no url', () => { + renderKeyPhoto() + expect(screen.queryByRole('img')).not.toBeInTheDocument() + }) + + it('should render image and link if has url', () => { + const url = 'https://example.com/img.jpg' + renderKeyPhoto(url) + + const imgNode = screen.queryByRole('img') + expect(imgNode).toBeVisible() + expect(imgNode).toHaveAttribute('src', url) + }) +}) diff --git a/frontend/packages/data-portal/app/components/HydrateAtomsProvider.tsx b/frontend/packages/data-portal/app/components/HydrateAtomsProvider.tsx new file mode 100644 index 000000000..6c3fa9d21 --- /dev/null +++ b/frontend/packages/data-portal/app/components/HydrateAtomsProvider.tsx @@ -0,0 +1,36 @@ +import { Provider } from 'jotai' +import { useHydrateAtoms } from 'jotai/utils' +import { ReactNode } from 'react' + +import { AtomTupleWithValue } from 'app/types/state' + +function HydrateAtoms({ + initialValues, + children, +}: { + initialValues: AtomTupleWithValue[] + children: ReactNode +}) { + useHydrateAtoms(initialValues) + return children +} + +/** + * Renders component tree with initial values for global state. The + * `initialValues` prop should be an array of tuple pairs where the first + * element is the atom definition and the second element is the initial value of + * the atom. + */ +export function HydrateAtomsProvider({ + initialValues, + children, +}: { + initialValues: AtomTupleWithValue[] + children: ReactNode +}) { + return ( + + {children} + + ) +} diff --git a/frontend/packages/data-portal/app/components/InlineMetadata.test.tsx b/frontend/packages/data-portal/app/components/InlineMetadata.test.tsx new file mode 100644 index 000000000..cfc3573b2 --- /dev/null +++ b/frontend/packages/data-portal/app/components/InlineMetadata.test.tsx @@ -0,0 +1,32 @@ +import { render, screen } from '@testing-library/react' + +import { InlineMetadata, Metadata } from './InlineMetadata' + +const TEST_FIELDS: Metadata[] = [ + { + key: 'key1', + value: 'value1', + }, + { + key: 'key2', + value: 'value2', + }, +] + +describe('', () => { + it('should render fields', () => { + render() + + TEST_FIELDS.forEach((field) => { + expect(screen.getByText(`${field.key}:`)).toBeInTheDocument() + expect(screen.getByText(field.value)).toBeInTheDocument() + }) + }) + + it('should render label if defined', () => { + const label = 'Test label' + render() + + expect(screen.getByText(label)).toBeInTheDocument() + }) +}) diff --git a/frontend/packages/data-portal/app/components/KeyPhoto.test.tsx b/frontend/packages/data-portal/app/components/KeyPhoto.test.tsx new file mode 100644 index 000000000..a01ab8bb8 --- /dev/null +++ b/frontend/packages/data-portal/app/components/KeyPhoto.test.tsx @@ -0,0 +1,19 @@ +import { render, screen } from '@testing-library/react' + +import { KeyPhoto } from './KeyPhoto' + +describe('', () => { + it('should show fallback if no image is defined', () => { + render() + expect(screen.queryByRole('img')).not.toBeInTheDocument() + }) + + it('should show image if defined', () => { + const src = 'https://example.com/image.jpg' + render() + + const imgNode = screen.queryByRole('img') + expect(imgNode).toBeVisible() + expect(imgNode).toHaveAttribute('src', src) + }) +}) diff --git a/frontend/packages/data-portal/app/components/MenuDropdown.test.tsx b/frontend/packages/data-portal/app/components/MenuDropdown.test.tsx new file mode 100644 index 000000000..3ac0bf5e9 --- /dev/null +++ b/frontend/packages/data-portal/app/components/MenuDropdown.test.tsx @@ -0,0 +1,28 @@ +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { MenuDropdown } from './MenuDropdown' + +describe('', () => { + it('should hide menu initially', () => { + render( + +

content

+
, + ) + + expect(screen.queryByText('content')).not.toBeInTheDocument() + }) + + it('should open menu on click', async () => { + render( + +

content

+
, + ) + + await userEvent.click(screen.getByRole('button')) + + expect(screen.queryByText('content')).toBeVisible() + }) +}) diff --git a/frontend/packages/data-portal/app/components/NoFilteredResults.test.tsx b/frontend/packages/data-portal/app/components/NoFilteredResults.test.tsx new file mode 100644 index 000000000..7078afc36 --- /dev/null +++ b/frontend/packages/data-portal/app/components/NoFilteredResults.test.tsx @@ -0,0 +1,52 @@ +import { jest } from '@jest/globals' +import { createRemixStub } from '@remix-run/testing' +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +const mockReset = jest.fn() + +jest.unstable_mockModule('app/hooks/useFilter', () => ({ + __esModule: true, + useFilter: () => ({ + reset: mockReset, + }), +})) + +async function renderNoFilteredResults(showSearchTip = false) { + const { NoFilteredResults } = await import('./NoFilteredResults') + + function NoFilteredResultsWrapper() { + return + } + + const NoFilteredResultsStub = createRemixStub([ + { + path: '/', + Component: NoFilteredResultsWrapper, + }, + ]) + + render() +} + +describe('', () => { + it('should not show search tip if false', async () => { + await renderNoFilteredResults() + + expect(screen.queryByText('noResultsSearch')).not.toBeInTheDocument() + }) + + it('should show search tip if true', async () => { + await renderNoFilteredResults(true) + + expect(screen.queryByText('noResultsSearch')).toBeVisible() + }) + + it('should reset state on click', async () => { + await renderNoFilteredResults() + + expect(mockReset).not.toHaveBeenCalled() + await userEvent.click(screen.getByRole('button')) + expect(mockReset).toHaveBeenCalled() + }) +}) diff --git a/frontend/packages/data-portal/app/components/Select.test.tsx b/frontend/packages/data-portal/app/components/Select.test.tsx new file mode 100644 index 000000000..f3292631c --- /dev/null +++ b/frontend/packages/data-portal/app/components/Select.test.tsx @@ -0,0 +1,121 @@ +import { jest } from '@jest/globals' +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { Select, SelectOption, SelectProps } from './Select' + +const TEST_OPTIONS: SelectOption[] = Array(3) + .fill(null) + .map((_, idx) => ({ + key: `test${idx}`, + value: `Value ${idx}`, + label: `Label ${idx}`, + })) + +function renderSelect({ + activeKey = null, + label = 'Test Label', + onChange = jest.fn(), + ...props +}: Partial = {}) { + return render( + ', () => { + it('should render title', () => { + const title = 'Test Title' + + renderSelect({ title }) + expect(screen.queryByText(`${title}:`)).toBeVisible() + }) + + it('should render label', () => { + renderSelect() + expect(screen.queryByText('Test Label')).toBeVisible() + }) + + it('should show active option', () => { + const activeOption = TEST_OPTIONS[1] + + renderSelect({ activeKey: activeOption.key }) + expect(screen.queryByText(activeOption.value)).toBeVisible() + }) + + it('should not show active option when showActiveValue=false', () => { + const activeOption = TEST_OPTIONS[1] + + renderSelect({ activeKey: activeOption.key, showActiveValue: false }) + expect(screen.queryByText(activeOption.value)).not.toBeInTheDocument() + }) + + it('should render tooltip', () => { + renderSelect({ tooltip: 'test tooltip' }) + + const tooltipNode = screen.queryByRole('tooltip') + expect(tooltipNode).toBeVisible() + }) + + it('should show all options when clicked on', async () => { + renderSelect() + + await userEvent.click(screen.getByRole('button')) + + TEST_OPTIONS.forEach((option) => { + expect(screen.queryByText(option.label ?? option.key)).toBeVisible() + expect(screen.queryByText(option.value)).toBeVisible() + }) + }) + + it('should not show option details', async () => { + renderSelect({ showDetails: false }) + + await userEvent.click(screen.getByRole('button')) + + TEST_OPTIONS.forEach((option) => { + expect(screen.queryByText(option.label ?? option.key)).toBeVisible() + expect(screen.queryByText(option.value)).not.toBeInTheDocument() + }) + }) + + it('should close on click away', async () => { + renderSelect() + + await userEvent.click(screen.getByRole('button')) + + render() + await userEvent.click(screen.getByRole('button', { name: 'clickaway' })) + + TEST_OPTIONS.forEach((option) => { + expect( + screen.queryByText(option.label ?? option.key), + ).not.toBeInTheDocument() + + expect(screen.queryByText(option.value)).not.toBeInTheDocument() + }) + }) + + it('should set active value on click', async () => { + renderSelect() + + const activeOption = TEST_OPTIONS[1] + expect(screen.queryByText(activeOption.value)).not.toBeInTheDocument() + + await userEvent.click(screen.getByRole('button')) + await userEvent.click( + screen.getByText(`${activeOption.label ?? activeOption.key}`), + ) + + expect( + screen.queryByText(activeOption.label ?? activeOption.key), + ).not.toBeInTheDocument() + expect(screen.queryByText(activeOption.value)).not.toBeInTheDocument() + }) +}) diff --git a/frontend/packages/data-portal/app/components/Select.tsx b/frontend/packages/data-portal/app/components/Select.tsx index dc95b316c..733ff48a4 100644 --- a/frontend/packages/data-portal/app/components/Select.tsx +++ b/frontend/packages/data-portal/app/components/Select.tsx @@ -26,6 +26,21 @@ export interface SelectOption { component?: JSX.Element } +export interface SelectProps { + activeKey: string | null + className?: string + dropdownClasses?: Partial + dropdownPopperBaseProps?: Partial + label: ReactNode + onChange(key: string | null): void + options: SelectOption[] + showActiveValue?: boolean + showDetails?: boolean + title?: string + tooltip?: ReactNode + tooltipProps?: Partial +} + export function Select({ activeKey, className, @@ -39,20 +54,7 @@ export function Select({ title, tooltip, tooltipProps, -}: { - activeKey: string | null - className?: string - dropdownClasses?: Partial - dropdownPopperBaseProps?: Partial - label: ReactNode - onChange(key: string | null): void - options: SelectOption[] - showActiveValue?: boolean - showDetails?: boolean - title?: string - tooltip?: ReactNode - tooltipProps?: Partial -}) { +}: SelectProps) { const activeOption = useMemo( () => options.find((option) => option.key === activeKey), [activeKey, options], @@ -113,7 +115,7 @@ export function Select({ )} {tooltip && ( - + ', () => { + TYPES.forEach((type) => { + it(`should render correct text for ${type}`, () => { + render() + + expect(screen.queryByText(TYPE_I18N_MAP[type])).toBeVisible() + }) + }) + + it('should show tooltip if defined', () => { + render() + + expect(screen.queryByRole('tooltip')).toBeVisible() + }) +}) diff --git a/frontend/packages/data-portal/app/components/TomogramTypeBadge.tsx b/frontend/packages/data-portal/app/components/TomogramTypeBadge.tsx index 194bab3ec..f6a76dc47 100644 --- a/frontend/packages/data-portal/app/components/TomogramTypeBadge.tsx +++ b/frontend/packages/data-portal/app/components/TomogramTypeBadge.tsx @@ -42,6 +42,7 @@ export function TomogramTypeBadge({ /> } placement="top" + role="tooltip" > {badge} diff --git a/frontend/packages/data-portal/app/hooks/useRunById.ts b/frontend/packages/data-portal/app/hooks/useRunById.ts index d68532c00..34ed37bcf 100644 --- a/frontend/packages/data-portal/app/hooks/useRunById.ts +++ b/frontend/packages/data-portal/app/hooks/useRunById.ts @@ -2,7 +2,7 @@ import { useTypedLoaderData } from 'remix-typedjson' import { GetRunByIdQuery } from 'app/__generated__/graphql' import { GetRunByIdV2Query } from 'app/__generated_v2__/graphql' -import { isNotNullish } from 'app/utils/nullish' +import { isDefined } from 'app/utils/nullish' export function useRunById() { const { v1, v2 } = useTypedLoaderData<{ @@ -54,7 +54,7 @@ export function useRunById() { const annotationSoftwares = v1.annotations_for_softwares .map((annotation) => annotation.annotation_software) - .filter(isNotNullish) + .filter(isDefined) const resolutions = v1.tomograms_for_resolutions.map( (tomogram) => tomogram.voxel_spacing, diff --git a/frontend/packages/data-portal/app/state/filterHistory.ts b/frontend/packages/data-portal/app/state/filterHistory.ts index b268536ff..7bc6fa60b 100644 --- a/frontend/packages/data-portal/app/state/filterHistory.ts +++ b/frontend/packages/data-portal/app/state/filterHistory.ts @@ -4,10 +4,10 @@ import { useEffect } from 'react' import { QueryParams } from 'app/constants/query' -const previousBrowseDatasetParamsAtom = atom('') -const previousSingleDatasetParamsAtom = atom('') -const previousDepositionIdAtom = atom(null) -const previousSingleDepositionParamsAtom = atom('') +export const previousBrowseDatasetParamsAtom = atom('') +export const previousSingleDatasetParamsAtom = atom('') +export const previousDepositionIdAtom = atom(null) +export const previousSingleDepositionParamsAtom = atom('') export function useBrowseDatasetFilterHistory() { const [previousBrowseDatasetParams, setPreviousBrowseDatasetParams] = useAtom( diff --git a/frontend/packages/data-portal/app/types/state.ts b/frontend/packages/data-portal/app/types/state.ts new file mode 100644 index 000000000..1e469df9e --- /dev/null +++ b/frontend/packages/data-portal/app/types/state.ts @@ -0,0 +1,12 @@ +/** + * Type definitions exported from useHydrateAtoms.d.ts + */ + +import { WritableAtom } from 'jotai' + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type AnyWritableAtom = WritableAtom +export type AtomTupleWithValue = readonly [ + A, + V, +] diff --git a/frontend/packages/data-portal/app/utils/nullish.test.ts b/frontend/packages/data-portal/app/utils/nullish.test.ts new file mode 100644 index 000000000..b27a3464f --- /dev/null +++ b/frontend/packages/data-portal/app/utils/nullish.test.ts @@ -0,0 +1,15 @@ +import { isDefined } from './nullish' + +describe('isDefined()', () => { + it('should return true if non-nullish', () => { + const testCases = ['foo', 1, true, false, [], {}] + + testCases.forEach((testCase) => expect(isDefined(testCase)).toBe(true)) + }) + + it('should return false if nullish', () => { + const testCases = [null, undefined] + + testCases.forEach((testCase) => expect(isDefined(testCase)).toBe(false)) + }) +}) diff --git a/frontend/packages/data-portal/app/utils/nullish.ts b/frontend/packages/data-portal/app/utils/nullish.ts index cfdd59c96..eb0788f47 100644 --- a/frontend/packages/data-portal/app/utils/nullish.ts +++ b/frontend/packages/data-portal/app/utils/nullish.ts @@ -1,4 +1,4 @@ /** Checks nullish and updates the type. */ -export function isNotNullish(x: T): x is NonNullable { +export function isDefined(x: T): x is NonNullable { return x != null } diff --git a/frontend/packages/data-portal/app/utils/proxy.test.ts b/frontend/packages/data-portal/app/utils/proxy.test.ts deleted file mode 100644 index 46720f3f4..000000000 --- a/frontend/packages/data-portal/app/utils/proxy.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -/* eslint-disable jest/expect-expect */ - -import { Datasets_Bool_Exp } from 'app/__generated__/graphql' - -import { getSelfCreatingObject } from './proxy' - -describe('proxy', () => { - describe('getSelfCreatingObject()', () => { - it('should create nested objects if it does not exist', () => { - interface Person { - name: string - address: { - street: string - city: string - } - } - - const person = getSelfCreatingObject() - const expected: Person = { - name: 'Foo Bar', - address: { - street: 'Foo', - city: 'Bar', - }, - } - - expect(person).not.toMatchObject(expected) - - person.name = 'Foo Bar' - person.address.street = 'Foo' - person.address.city = 'Bar' - - expect(person).toMatchObject(expected) - }) - - it('should shit', () => { - const filter = getSelfCreatingObject() - - filter.runs.tomogram_voxel_spacings.annotations.ground_truth_status._eq = - true - }) - }) -}) diff --git a/frontend/packages/data-portal/app/utils/proxy.ts b/frontend/packages/data-portal/app/utils/proxy.ts deleted file mode 100644 index 0bf68fa1d..000000000 --- a/frontend/packages/data-portal/app/utils/proxy.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ - -import { DeepNonNullable } from 'utility-types' - -function convertToPlainObject>( - obj: T, -): Partial { - const result: Record = {} - - // eslint-disable-next-line no-restricted-syntax - for (const key in obj) { - // eslint-disable-next-line no-prototype-builtins - if (obj.hasOwnProperty(key)) { - const value = obj[key as keyof T] - - if (value !== null && typeof value === 'object') { - if (Array.isArray(value)) { - result[key] = value.map((item) => - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - typeof item === 'object' ? convertToPlainObject(item) : item, - ) - } else { - result[key] = convertToPlainObject(value as T) - } - } else if (value !== undefined) { - result[key] = value - } - } - } - - return result as Partial -} - -export function getSelfCreatingObject(): DeepNonNullable { - return new Proxy( - {}, - { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - get(target: Record, prop: any) { - if (prop === 'toJSON') { - return convertToPlainObject(target) - } - - if (!(prop in target)) { - // Create an empty object if the property doesn't exist - // eslint-disable-next-line no-param-reassign - target[prop] = getSelfCreatingObject() - } - - return target[prop] - }, - }, - ) as DeepNonNullable -} diff --git a/frontend/packages/data-portal/app/utils/table.ts b/frontend/packages/data-portal/app/utils/table.ts index c1c42f422..4ccd454f5 100644 --- a/frontend/packages/data-portal/app/utils/table.ts +++ b/frontend/packages/data-portal/app/utils/table.ts @@ -1,6 +1,6 @@ import { TableData } from 'app/types/table' -import { isNotNullish } from './nullish' +import { isDefined } from './nullish' export function getTableData(...metadata: Array) { return metadata @@ -8,7 +8,7 @@ export function getTableData(...metadata: Array) { .map((data) => { const values = ( data.values instanceof Function ? data.values() : data.values - ).filter((value) => isNotNullish(value) && value !== '') + ).filter((value) => isDefined(value) && value !== '') return { ...data, diff --git a/frontend/packages/data-portal/e2e/apollo.ts b/frontend/packages/data-portal/e2e/apollo.ts index e9b9bcc1f..d5852a792 100644 --- a/frontend/packages/data-portal/e2e/apollo.ts +++ b/frontend/packages/data-portal/e2e/apollo.ts @@ -2,6 +2,12 @@ * Version of `apollo.server.ts` that is safe to use in e2e tests. */ +// For some reason we need to use a `default` export even though the types +// do not have one. It might be playwright doing something weird with the imports +// or the apollo types have to be updated to export a default export. +// TODO remove ts-ignore +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore import apollo from '@apollo/client' import { ENVIRONMENT_CONTEXT_DEFAULT_VALUE } from '../app/context/Environment.context' diff --git a/frontend/packages/data-portal/jest.config.cjs b/frontend/packages/data-portal/jest.config.cjs index 974e4aabf..b16426c25 100644 --- a/frontend/packages/data-portal/jest.config.cjs +++ b/frontend/packages/data-portal/jest.config.cjs @@ -1,7 +1,7 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { preset: 'ts-jest/presets/default-esm', - setupFilesAfterEnv: ['@testing-library/jest-dom'], + setupFilesAfterEnv: ['@testing-library/jest-dom', '/setupTests.ts'], testEnvironment: 'jsdom', testPathIgnorePatterns: ['./e2e'], diff --git a/frontend/packages/data-portal/package.json b/frontend/packages/data-portal/package.json index afcd7c4af..7c4098a3f 100644 --- a/frontend/packages/data-portal/package.json +++ b/frontend/packages/data-portal/package.json @@ -46,12 +46,12 @@ "@mui/lab": "^5.0.0-alpha.148", "@mui/material": "^5.14.13", "@react-hookz/web": "^23.1.0", - "@remix-run/css-bundle": "^2.0.1", - "@remix-run/express": "^2.0.1", - "@remix-run/node": "^2.0.1", - "@remix-run/react": "^2.0.1", - "@remix-run/server-runtime": "^2.0.1", - "@remix-run/testing": "^2.0.1", + "@remix-run/css-bundle": "^2.15.0", + "@remix-run/express": "^2.15.0", + "@remix-run/node": "^2.15.0", + "@remix-run/react": "^2.15.0", + "@remix-run/server-runtime": "^2.15.0", + "@remix-run/testing": "^2.15.0", "@tanstack/react-table": "^8.10.6", "axios": "^1.7.8", "axios-cache-interceptor": "^1.3.2", @@ -99,10 +99,11 @@ "@jest/globals": "^29.7.0", "@parcel/watcher": "^2.3.0", "@playwright/test": "^1.41.2", - "@remix-run/dev": "^2.0.1", + "@remix-run/dev": "^2.15.0", "@tailwindcss/typography": "^0.5.10", "@testing-library/jest-dom": "^6.4.5", "@testing-library/react": "^15.0.7", + "@testing-library/user-event": "^14.5.2", "@types/compression": "^1.7.3", "@types/express": "^4.17.19", "@types/jest": "^29.5.12", @@ -119,8 +120,8 @@ "autoprefixer": "^10.4.16", "dotenv": "^16.3.1", "eslint": "^8.51.0", - "eslint-config-cryoet-data-portal": "*", - "eslint-plugin-cryoet-data-portal": "*", + "eslint-config-cryoet-data-portal": "workspace:*", + "eslint-plugin-cryoet-data-portal": "workspace:*", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "playwright": "^1.41.2", diff --git a/frontend/packages/data-portal/public/locales/en/translation.json b/frontend/packages/data-portal/public/locales/en/translation.json index 9cba70be6..5614b28d0 100644 --- a/frontend/packages/data-portal/public/locales/en/translation.json +++ b/frontend/packages/data-portal/public/locales/en/translation.json @@ -118,10 +118,10 @@ "datasetName": "Dataset Name", "datasetOverview": "Dataset Overview", "datasetTitle": "Dataset Title", - "datasetsWithDepositionData": "Datasets with Deposition Data", "datasets": "Datasets", "datasetsDescription": "Datasets are contributed sets of files associated with imaging one sample type with the same experimental conditions.", "datasetsTab": "Datasets {{count}}", + "datasetsWithDepositionData": "Datasets with Deposition Data", "deposition": "Deposition", "depositionAnnotationsOnly": "Deposition annotations only", "depositionData": "Deposition Data", @@ -239,12 +239,12 @@ "methodTypeManual": "Manual: Annotations were created by hand.", "microscopeManufacturer": "Microscope Manufacturer", "microscopeModel": "Microscope model", - "mlChallengeStartDate": "November 6, 2024", "mlChallengeEndDate": "February 5, 2025", - "mlCompetitionLearnMore": "Learn More", - "mlCompetitionHasBegun": "ML Competition has begun. Enter for cash prizes. $t(mlCompetitionLearnMore)", - "mlCompetitionEnding": "ML Competition is ending in {{days}} days. Compete for cash prizes. $t(mlCompetitionLearnMore)", + "mlChallengeStartDate": "November 6, 2024", "mlCompetitionEnded": "Congratulations to the ML Competition winners! $t(mlCompetitionLearnMore) about the winning models.", + "mlCompetitionEnding": "ML Competition is ending in {{days}} days. Compete for cash prizes. $t(mlCompetitionLearnMore)", + "mlCompetitionHasBegun": "ML Competition has begun. Enter for cash prizes. $t(mlCompetitionLearnMore)", + "mlCompetitionLearnMore": "Learn More", "modelWeights": "Model Weights", "moderate": "Moderate", "moreInfo": "More Info", @@ -334,6 +334,7 @@ "relatedDatabases": "Related Databases", "relatedEmpiarEntry": "Related EMPIAR Entry", "releaseDate": "Release Date", + "removeFilter": "Remove Filter", "reportIssueOnGithub": "Report Issue on GitHub", "resetAll": "Reset All", "resolutionsAvailable": "Samplings Available", @@ -378,8 +379,8 @@ "species": "Species", "sphericalAberrationConstant": "Spherical Aberration Constant", "sponsoredBy": "Sponsored By", - "starts": "Starts", "started": "Started", + "starts": "Starts", "stepCount": "Step {{count}} of {{max}}", "submitFeedback": "Submit Feedback", "submittedByDatasetAuthor": "Submitted by Dataset Author", diff --git a/frontend/packages/data-portal/setupTests.ts b/frontend/packages/data-portal/setupTests.ts new file mode 100644 index 000000000..b5806f817 --- /dev/null +++ b/frontend/packages/data-portal/setupTests.ts @@ -0,0 +1,20 @@ +import { jest } from '@jest/globals' + +jest.mock('react-i18next', () => ({ + // this mock makes sure any components using the translate hook can use it without a warning being shown + useTranslation: () => ({ + t: (i18nKey: string) => i18nKey, + i18n: { + changeLanguage: () => new Promise(() => {}), + }, + }), + + initReactI18next: { + type: '3rdParty', + init: () => {}, + }, +})) + +jest.mock('@web3-storage/multipart-parser', () => ({ + parseMultipart: jest.fn(), +})) diff --git a/frontend/packages/eslint-config/package.json b/frontend/packages/eslint-config/package.json index 2b92dc6e2..677646015 100644 --- a/frontend/packages/eslint-config/package.json +++ b/frontend/packages/eslint-config/package.json @@ -14,7 +14,7 @@ "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-cryoet-data-portal": "*", + "eslint-plugin-cryoet-data-portal": "workspace:*", "eslint-plugin-import": "^2.28.1", "eslint-plugin-jest": "^27.4.2", "eslint-plugin-jest-dom": "^5.1.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 4681022b8..4b80069ea 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -74,23 +74,23 @@ importers: specifier: ^23.1.0 version: 23.1.0(react-dom@18.2.0)(react@18.2.0) '@remix-run/css-bundle': - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^2.15.0 + version: 2.15.0 '@remix-run/express': - specifier: ^2.0.1 - version: 2.0.1(express@4.21.1)(typescript@5.2.2) + specifier: ^2.15.0 + version: 2.15.0(express@4.21.1)(typescript@5.2.2) '@remix-run/node': - specifier: ^2.0.1 - version: 2.0.1(typescript@5.2.2) + specifier: ^2.15.0 + version: 2.15.0(typescript@5.2.2) '@remix-run/react': - specifier: ^2.0.1 - version: 2.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) + specifier: ^2.15.0 + version: 2.15.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) '@remix-run/server-runtime': - specifier: ^2.0.1 - version: 2.0.1(typescript@5.2.2) + specifier: ^2.15.0 + version: 2.15.0(typescript@5.2.2) '@remix-run/testing': - specifier: ^2.0.1 - version: 2.9.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) + specifier: ^2.15.0 + version: 2.15.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) '@tanstack/react-table': specifier: ^8.10.6 version: 8.10.6(react-dom@18.2.0)(react@18.2.0) @@ -198,10 +198,10 @@ importers: version: 2.0.0 remix-i18next: specifier: ^5.4.0 - version: 5.4.0(@remix-run/react@2.0.1)(@remix-run/server-runtime@2.0.1)(i18next@23.7.6)(react-i18next@13.5.0)(react@18.2.0) + version: 5.4.0(@remix-run/react@2.15.0)(@remix-run/server-runtime@2.15.0)(i18next@23.7.6)(react-i18next@13.5.0)(react@18.2.0) remix-typedjson: specifier: ^0.2.2 - version: 0.2.2(@remix-run/react@2.0.1)(@remix-run/server-runtime@2.0.1)(react@18.2.0) + version: 0.2.2(@remix-run/react@2.15.0)(@remix-run/server-runtime@2.15.0)(react@18.2.0) source-map-support: specifier: ^0.5.21 version: 0.5.21 @@ -228,8 +228,8 @@ importers: specifier: ^1.41.2 version: 1.41.2 '@remix-run/dev': - specifier: ^2.0.1 - version: 2.0.1(@types/node@20.8.4)(ts-node@10.9.1)(typescript@5.2.2) + specifier: ^2.15.0 + version: 2.15.0(@remix-run/react@2.15.0)(@types/node@20.8.4)(ts-node@10.9.1)(typescript@5.2.2) '@tailwindcss/typography': specifier: ^0.5.10 version: 0.5.10(tailwindcss@3.3.3) @@ -239,6 +239,9 @@ importers: '@testing-library/react': specifier: ^15.0.7 version: 15.0.7(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@testing-library/user-event': + specifier: ^14.5.2 + version: 14.5.2(@testing-library/dom@10.1.0) '@types/compression': specifier: ^1.7.3 version: 1.7.3 @@ -288,10 +291,10 @@ importers: specifier: ^8.51.0 version: 8.51.0 eslint-config-cryoet-data-portal: - specifier: '*' + specifier: workspace:* version: link:../eslint-config eslint-plugin-cryoet-data-portal: - specifier: '*' + specifier: workspace:* version: link:../eslint-plugin jest: specifier: ^29.7.0 @@ -357,7 +360,7 @@ importers: specifier: ^3.6.1 version: 3.6.1(@typescript-eslint/parser@6.7.3)(eslint-plugin-import@2.28.1)(eslint@8.51.0) eslint-plugin-cryoet-data-portal: - specifier: '*' + specifier: workspace:* version: link:../eslint-plugin eslint-plugin-import: specifier: ^2.28.1 @@ -1371,10 +1374,10 @@ packages: /@emotion/hash@0.9.1: resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + dev: false /@emotion/hash@0.9.2: resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} - dev: false /@emotion/is-prop-valid@0.8.8: resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} @@ -3430,41 +3433,54 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@remix-run/css-bundle@2.0.1: - resolution: {integrity: sha512-PDAak97HvrSa6Pu84iN14o8NNitqLeyO0iH9zqWNhrsO2nFELUOzQ/02H/9QWmmIYgVpbUIQxJlp70ZEAV2dyw==} + /@remix-run/css-bundle@2.15.0: + resolution: {integrity: sha512-Jf4AHdObVyGbPf5V4rIB7cRLdluFkzKvrHglDUrrH1KvbD+jNulQt+Kz3bjbEeEdyUSK+LdVMD2E2zOx+ZNXyg==} engines: {node: '>=18.0.0'} dev: false - /@remix-run/dev@2.0.1(@types/node@20.8.4)(ts-node@10.9.1)(typescript@5.2.2): - resolution: {integrity: sha512-FxlbgCBXUzKxBSs2OfNoBUadcARr4S7S4JQ28t7MLcIsfJI/uHmGAMXClatsgeZuRvPK/Zx/W3B4uho1FTfQVA==} + /@remix-run/dev@2.15.0(@remix-run/react@2.15.0)(@types/node@20.8.4)(ts-node@10.9.1)(typescript@5.2.2): + resolution: {integrity: sha512-iXV6u9PBwFc7KriDpVcjqLGJzZZd6ZOrxewen7hoH0OBzGwjkhtm46BTQEJrZ/e/dzlU1IU/0ylH29tN9BZoyg==} engines: {node: '>=18.0.0'} hasBin: true peerDependencies: - '@remix-run/serve': ^2.0.1 + '@remix-run/react': ^2.15.0 + '@remix-run/serve': ^2.15.0 typescript: ^5.1.0 + vite: ^4.5.3 + wrangler: ^3.28.2 peerDependenciesMeta: '@remix-run/serve': optional: true typescript: optional: true + vite: + optional: true + wrangler: + optional: true dependencies: '@babel/core': 7.23.0 - '@babel/generator': 7.23.0 - '@babel/parser': 7.23.0 + '@babel/generator': 7.24.6 + '@babel/parser': 7.24.6 '@babel/plugin-syntax-decorators': 7.22.10(@babel/core@7.23.0) '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.0) '@babel/preset-typescript': 7.23.0(@babel/core@7.23.0) '@babel/traverse': 7.24.6 + '@babel/types': 7.24.6 '@mdx-js/mdx': 2.3.0 '@npmcli/package-json': 4.0.1 - '@remix-run/server-runtime': 2.0.1(typescript@5.2.2) + '@remix-run/node': 2.15.0(typescript@5.2.2) + '@remix-run/react': 2.15.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) + '@remix-run/router': 1.21.0 + '@remix-run/server-runtime': 2.15.0(typescript@5.2.2) '@types/mdx': 2.0.8 '@vanilla-extract/integration': 6.2.2(@types/node@20.8.4) arg: 5.0.2 cacache: 17.1.4 chalk: 4.1.2 chokidar: 3.5.3 + cross-spawn: 7.0.3 dotenv: 16.3.1 + es-module-lexer: 1.5.4 esbuild: 0.17.6 esbuild-plugins-node-modules-polyfill: 1.6.1(esbuild@0.17.6) execa: 5.1.1 @@ -3478,7 +3494,6 @@ packages: lodash: 4.17.21 lodash.debounce: 4.0.8 minimatch: 9.0.3 - node-fetch: 2.7.0 ora: 5.4.1 picocolors: 1.0.0 picomatch: 2.3.1 @@ -3493,15 +3508,17 @@ packages: remark-frontmatter: 4.0.1 remark-mdx-frontmatter: 1.1.1 semver: 7.5.4 + set-cookie-parser: 2.6.0 tar-fs: 2.1.1 tsconfig-paths: 4.2.0 typescript: 5.2.2 + valibot: 0.41.0(typescript@5.2.2) + vite-node: 1.6.0(@types/node@20.8.4) ws: 7.5.10 transitivePeerDependencies: - '@types/node' - bluebird - bufferutil - - encoding - less - lightningcss - sass @@ -3513,43 +3530,23 @@ packages: - utf-8-validate dev: true - /@remix-run/express@2.0.1(express@4.21.1)(typescript@5.2.2): - resolution: {integrity: sha512-YwqWF+Se6EoKL7uJhA/55BwP6kxIgDo//kHoh8miaMvVUKa1KMLru79kqU74d7PleYf9Qj4i2cXygz1mMl032w==} + /@remix-run/express@2.15.0(express@4.21.1)(typescript@5.2.2): + resolution: {integrity: sha512-MyCXVmbrxeo06zJECuaOUQ01x13zEkmMUkFzaHESWMBxnTPGbtKF4Gb0iF6TrMFiSeaKptUU4JBvLeHooPOryA==} engines: {node: '>=18.0.0'} peerDependencies: - express: ^4.17.1 + express: ^4.20.0 typescript: ^5.1.0 peerDependenciesMeta: typescript: optional: true dependencies: - '@remix-run/node': 2.0.1(typescript@5.2.2) + '@remix-run/node': 2.15.0(typescript@5.2.2) express: 4.21.1 typescript: 5.2.2 dev: false - /@remix-run/node@2.0.1(typescript@5.2.2): - resolution: {integrity: sha512-pWsbmkNRb7azYomh1IGSKeW68hkwBBp6L2AWvfKSq2r2MJXHCzqgAJEc0uWkEUx6OtFbVNOg27g/cMCyKvrjIA==} - engines: {node: '>=18.0.0'} - peerDependencies: - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@remix-run/server-runtime': 2.0.1(typescript@5.2.2) - '@remix-run/web-fetch': 4.4.1 - '@remix-run/web-file': 3.1.0 - '@remix-run/web-stream': 1.1.0 - '@web3-storage/multipart-parser': 1.0.0 - cookie-signature: 1.2.1 - source-map-support: 0.5.21 - stream-slice: 0.1.2 - typescript: 5.2.2 - dev: false - - /@remix-run/node@2.9.1(typescript@5.2.2): - resolution: {integrity: sha512-shicVsSmXepj4zotWHR2kLmyYCxQ25mHmfBL11ODIcIs7iSmQO+W7CNbmX1jcRvhHki/v+S/n4fMm0iKNeJ92w==} + /@remix-run/node@2.15.0(typescript@5.2.2): + resolution: {integrity: sha512-tWbR7pQ6gwj+MkGf6WVIYnjgfGfpdU8EOIa6xsCIRlrm0p3BtMz4jA3GvBWEpOuEnN5MV7CarVzhduaRzkZ0SQ==} engines: {node: '>=18.0.0'} peerDependencies: typescript: ^5.1.0 @@ -3557,7 +3554,7 @@ packages: typescript: optional: true dependencies: - '@remix-run/server-runtime': 2.9.1(typescript@5.2.2) + '@remix-run/server-runtime': 2.15.0(typescript@5.2.2) '@remix-run/web-fetch': 4.4.2 '@web3-storage/multipart-parser': 1.0.0 cookie-signature: 1.2.1 @@ -3565,10 +3562,9 @@ packages: stream-slice: 0.1.2 typescript: 5.2.2 undici: 6.16.0 - dev: false - /@remix-run/react@2.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): - resolution: {integrity: sha512-xZgJcRjzx9gjCzh7dDZGQJcmQPPFisMrDwhUuIzlSHuR2rEQCCGZPBLVCpbD1zhDfbdvOugbf2DLSmP2TEBXNA==} + /@remix-run/react@2.15.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): + resolution: {integrity: sha512-puqDbi9N/WfaUhzDnw2pACXtCB7ukrtFJ9ILwpEuhlaTBpjefifJ89igokW+tt1ePphIFMivAm/YspcbZdCQsA==} engines: {node: '>=18.0.0'} peerDependencies: react: ^18.0.0 @@ -3578,64 +3574,21 @@ packages: typescript: optional: true dependencies: - '@remix-run/router': 1.9.0 - '@remix-run/server-runtime': 2.0.1(typescript@5.2.2) + '@remix-run/router': 1.21.0 + '@remix-run/server-runtime': 2.15.0(typescript@5.2.2) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router-dom: 6.16.0(react-dom@18.2.0)(react@18.2.0) + react-router: 6.28.0(react@18.2.0) + react-router-dom: 6.28.0(react-dom@18.2.0)(react@18.2.0) + turbo-stream: 2.4.0 typescript: 5.2.2 - dev: false - /@remix-run/react@2.9.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): - resolution: {integrity: sha512-QQVZPS56okvDF3FBuGBjyKuYa6bXZvXFFlYeWfngI8ZnDbCzQLKV1oD0FWMhKuQxMaKs25uWg2YwGqwWTdin3w==} - engines: {node: '>=18.0.0'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@remix-run/router': 1.16.0 - '@remix-run/server-runtime': 2.9.1(typescript@5.2.2) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-router: 6.23.0(react@18.2.0) - react-router-dom: 6.23.0(react-dom@18.2.0)(react@18.2.0) - turbo-stream: 2.0.1 - typescript: 5.2.2 - dev: false - - /@remix-run/router@1.16.0: - resolution: {integrity: sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==} + /@remix-run/router@1.21.0: + resolution: {integrity: sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==} engines: {node: '>=14.0.0'} - dev: false - - /@remix-run/router@1.9.0: - resolution: {integrity: sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==} - engines: {node: '>=14.0.0'} - - /@remix-run/server-runtime@2.0.1(typescript@5.2.2): - resolution: {integrity: sha512-xCW2aw9EILx7F3orEHN2fcpEkNzZTRU8VzP7gS9pmHP45qteFqsY5Qg2/dnF17royWmeeBNhnXaJOgb76W1KEA==} - engines: {node: '>=18.0.0'} - peerDependencies: - typescript: ^5.1.0 - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@remix-run/router': 1.9.0 - '@types/cookie': 0.4.1 - '@web3-storage/multipart-parser': 1.0.0 - cookie: 0.4.2 - set-cookie-parser: 2.6.0 - source-map: 0.7.4 - type-fest: 4.3.2 - typescript: 5.2.2 - /@remix-run/server-runtime@2.9.1(typescript@5.2.2): - resolution: {integrity: sha512-6rRPiR+eMdTPkDojlYiZohVzXkD3+3X55ZvD78axMVocwGcDFFllpmgH9NSR2RKHW9eZDZUfKvNCwd/i9W6Xog==} + /@remix-run/server-runtime@2.15.0(typescript@5.2.2): + resolution: {integrity: sha512-FuM8vAg1sPskf4wn0ivbuj/7s9Qdh2wnKu+sVXqYz0a95gH5b73TuMzk6n3NMSkFVKKc6+UmlG1WLYre7L2LTg==} engines: {node: '>=18.0.0'} peerDependencies: typescript: ^5.1.0 @@ -3643,18 +3596,17 @@ packages: typescript: optional: true dependencies: - '@remix-run/router': 1.16.0 + '@remix-run/router': 1.21.0 '@types/cookie': 0.6.0 '@web3-storage/multipart-parser': 1.0.0 cookie: 0.6.0 set-cookie-parser: 2.6.0 source-map: 0.7.4 - turbo-stream: 2.0.1 + turbo-stream: 2.4.0 typescript: 5.2.2 - dev: false - /@remix-run/testing@2.9.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): - resolution: {integrity: sha512-BrZYicOtaBm4JBz5DJSUFQ9ym/q4Ii40dgw5GHKAemSoWWzr6QCtPBvaEWUMRqaXiLL1oiXux++aKG7/6nbppQ==} + /@remix-run/testing@2.15.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2): + resolution: {integrity: sha512-V8KZoQHENDHSi/kVRWWLTH9o3+iRmmsIrpeRKGHvY1DRvPUUIdOavTF5IarMoD5bflI0qXeH6x+cTvv9f+3hDg==} engines: {node: '>=18.0.0'} peerDependencies: react: ^18.0.0 @@ -3663,11 +3615,11 @@ packages: typescript: optional: true dependencies: - '@remix-run/node': 2.9.1(typescript@5.2.2) - '@remix-run/react': 2.9.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) - '@remix-run/router': 1.16.0 + '@remix-run/node': 2.15.0(typescript@5.2.2) + '@remix-run/react': 2.15.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) + '@remix-run/router': 1.21.0 react: 18.2.0 - react-router-dom: 6.23.0(react-dom@18.2.0)(react@18.2.0) + react-router-dom: 6.28.0(react-dom@18.2.0)(react@18.2.0) typescript: 5.2.2 transitivePeerDependencies: - react-dom @@ -3678,21 +3630,6 @@ packages: dependencies: '@remix-run/web-stream': 1.1.0 web-encoding: 1.1.5 - dev: false - - /@remix-run/web-fetch@4.4.1: - resolution: {integrity: sha512-xMceEGn2kvfeWS91nHSOhEQHPGgjFnmDVpWFZrbWPVdiTByMZIn421/tdSF6Kd1RsNsY+5Iwt3JFEKZHAcMQHw==} - engines: {node: ^10.17 || >=12.3} - dependencies: - '@remix-run/web-blob': 3.1.0 - '@remix-run/web-file': 3.1.0 - '@remix-run/web-form-data': 3.1.0 - '@remix-run/web-stream': 1.1.0 - '@web3-storage/multipart-parser': 1.0.0 - abort-controller: 3.0.0 - data-uri-to-buffer: 3.0.1 - mrmime: 1.0.1 - dev: false /@remix-run/web-fetch@4.4.2: resolution: {integrity: sha512-jgKfzA713/4kAW/oZ4bC3MoLWyjModOVDjFPNseVqcJKSafgIscrYL9G50SurEYLswPuoU3HzSbO0jQCMYWHhA==} @@ -3706,25 +3643,21 @@ packages: abort-controller: 3.0.0 data-uri-to-buffer: 3.0.1 mrmime: 1.0.1 - dev: false /@remix-run/web-file@3.1.0: resolution: {integrity: sha512-dW2MNGwoiEYhlspOAXFBasmLeYshyAyhIdrlXBi06Duex5tDr3ut2LFKVj7tyHLmn8nnNwFf1BjNbkQpygC2aQ==} dependencies: '@remix-run/web-blob': 3.1.0 - dev: false /@remix-run/web-form-data@3.1.0: resolution: {integrity: sha512-NdeohLMdrb+pHxMQ/Geuzdp0eqPbea+Ieo8M8Jx2lGC6TBHsgHzYcBvr0LyPdPVycNRDEpWpiDdCOdCryo3f9A==} dependencies: web-encoding: 1.1.5 - dev: false /@remix-run/web-stream@1.1.0: resolution: {integrity: sha512-KRJtwrjRV5Bb+pM7zxcTJkhIqWWSy+MYsIxHK+0m5atcznsf15YwUBWHWulZerV2+vvHH1Lp1DD7pw6qKW8SgA==} dependencies: web-streams-polyfill: 3.2.1 - dev: false /@repeaterjs/repeater@3.0.4: resolution: {integrity: sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==} @@ -3842,6 +3775,15 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true + /@testing-library/user-event@14.5.2(@testing-library/dom@10.1.0): + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + dependencies: + '@testing-library/dom': 10.1.0 + dev: true + /@tootallnate/once@2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} @@ -3916,12 +3858,8 @@ packages: '@types/node': 20.8.4 dev: true - /@types/cookie@0.4.1: - resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} - /@types/cookie@0.6.0: resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - dev: false /@types/debug@4.1.9: resolution: {integrity: sha512-8Hz50m2eoS56ldRlepxSBa6PWEVCtzUo/92HgLc2qTMnotJNIm7xP+UZhyWoYsyOdd5dxZ+NZLb24rsKyFs2ow==} @@ -4357,7 +4295,7 @@ packages: /@vanilla-extract/css@1.13.0: resolution: {integrity: sha512-JFFBXhnJrPlGqHBabagXqo5ghXw9mtV270ycIGyLDZG8NAK5eRwAYkMowAxuzK7wZSm67GnETWYB7b0AUmyttg==} dependencies: - '@emotion/hash': 0.9.1 + '@emotion/hash': 0.9.2 '@vanilla-extract/private': 1.0.3 ahocorasick: 1.0.2 chalk: 4.1.2 @@ -4476,7 +4414,6 @@ packages: /@zxing/text-encoding@0.9.0: resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==} requiresBuild: true - dev: false optional: true /abab@2.0.6: @@ -4488,7 +4425,6 @@ packages: engines: {node: '>=6.5'} dependencies: event-target-shim: 5.0.1 - dev: false /accept-language-parser@1.5.0: resolution: {integrity: sha512-QhyTbMLYo0BBGg1aWbeMG4ekWtds/31BrEU+DONOg/7ax23vxpL03Pb7/zBmha2v7vdD3AyzZVWBVGEZxKOXWw==} @@ -5481,16 +5417,10 @@ packages: /cookie-signature@1.2.1: resolution: {integrity: sha512-78KWk9T26NhzXtuL26cIJ8/qNHANyJ/ZYrmEXFzUmhZdjpBv+DlWlOANRTGBt48YcyslsLrj0bMLFTmXvLRCOw==} engines: {node: '>=6.6.0'} - dev: false - - /cookie@0.4.2: - resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} - engines: {node: '>= 0.6'} /cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} - dev: false /cookie@0.7.1: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} @@ -5624,7 +5554,6 @@ packages: /data-uri-to-buffer@3.0.1: resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==} engines: {node: '>= 6'} - dev: false /data-urls@3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} @@ -6039,6 +5968,10 @@ packages: safe-array-concat: 1.0.1 dev: false + /es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + dev: true + /es-set-tostringtag@2.0.1: resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} engines: {node: '>= 0.4'} @@ -6656,7 +6589,6 @@ packages: /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} - dev: false /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} @@ -7686,9 +7618,8 @@ packages: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 has-tostringtag: 1.0.0 - dev: false /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} @@ -7791,7 +7722,6 @@ packages: engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 - dev: false /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} @@ -9680,7 +9610,6 @@ packages: /mrmime@1.0.1: resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} engines: {node: '>=10'} - dev: false /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -9766,6 +9695,7 @@ packages: optional: true dependencies: whatwg-url: 5.0.0 + dev: false /node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -10788,51 +10718,26 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-router-dom@6.16.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' - dependencies: - '@remix-run/router': 1.9.0 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-router: 6.16.0(react@18.2.0) - dev: false - - /react-router-dom@6.23.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==} + /react-router-dom@6.28.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 1.16.0 + '@remix-run/router': 1.21.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 6.23.0(react@18.2.0) - dev: false + react-router: 6.28.0(react@18.2.0) - /react-router@6.16.0(react@18.2.0): - resolution: {integrity: sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA==} + /react-router@6.28.0(react@18.2.0): + resolution: {integrity: sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 1.9.0 + '@remix-run/router': 1.21.0 react: 18.2.0 - dev: false - - /react-router@6.23.0(react@18.2.0): - resolution: {integrity: sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' - dependencies: - '@remix-run/router': 1.16.0 - react: 18.2.0 - dev: false /react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} @@ -11045,7 +10950,7 @@ packages: resolution: {integrity: sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==} dev: false - /remix-i18next@5.4.0(@remix-run/react@2.0.1)(@remix-run/server-runtime@2.0.1)(i18next@23.7.6)(react-i18next@13.5.0)(react@18.2.0): + /remix-i18next@5.4.0(@remix-run/react@2.15.0)(@remix-run/server-runtime@2.15.0)(i18next@23.7.6)(react-i18next@13.5.0)(react@18.2.0): resolution: {integrity: sha512-4TGdkvSihr7X4qqpT31zleIyyRr3Z6MSu49t0zeZhFQrNqb6m7Ob/kVA5QfAl+jOa3Eow30bQ2fuOTBlQ07efA==} peerDependencies: '@remix-run/react': ^1.0.0 || ^2.0.0 @@ -11054,8 +10959,8 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-i18next: ^13.0.0 dependencies: - '@remix-run/react': 2.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) - '@remix-run/server-runtime': 2.0.1(typescript@5.2.2) + '@remix-run/react': 2.15.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) + '@remix-run/server-runtime': 2.15.0(typescript@5.2.2) accept-language-parser: 1.5.0 i18next: 23.7.6 intl-parse-accept-language: 1.0.0 @@ -11065,15 +10970,15 @@ packages: use-consistent-value: 1.0.0(react@18.2.0) dev: false - /remix-typedjson@0.2.2(@remix-run/react@2.0.1)(@remix-run/server-runtime@2.0.1)(react@18.2.0): + /remix-typedjson@0.2.2(@remix-run/react@2.15.0)(@remix-run/server-runtime@2.15.0)(react@18.2.0): resolution: {integrity: sha512-M6U7OHDReFoinDh5m2m7gJtmLlKrqxdeS+aygyIqHeTu7TLGahcQ8h0RZ0fs2JSd3QV1zJirG2zHpwCN1SK+TQ==} peerDependencies: '@remix-run/react': ^1.16.0 || ^2.0 '@remix-run/server-runtime': ^1.16.0 || ^2.0 react: ^17.0.2 || ^18.0.0 dependencies: - '@remix-run/react': 2.0.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) - '@remix-run/server-runtime': 2.0.1(typescript@5.2.2) + '@remix-run/react': 2.15.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.2.2) + '@remix-run/server-runtime': 2.15.0(typescript@5.2.2) react: 18.2.0 dev: false @@ -11520,7 +11425,6 @@ packages: /stream-slice@0.1.2: resolution: {integrity: sha512-QzQxpoacatkreL6jsxnVb7X5R/pGw9OUv2qWTYWnmLpg4NdN31snPy/f3TdQE1ZUXaThRvj1Zw4/OGg0ZkaLMA==} - dev: false /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} @@ -12063,6 +11967,7 @@ packages: /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false /tr46@3.0.0: resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} @@ -12212,9 +12117,8 @@ packages: tslib: 1.14.1 typescript: 5.2.2 - /turbo-stream@2.0.1: - resolution: {integrity: sha512-sm0ZtcX9YWh28p5X8t5McxC2uthrt9p+g0bGE0KTVFhnhNWefpSVCr+67zRNDUOfo4bpXwiOp7otO+dyQ7/y/A==} - dev: false + /turbo-stream@2.4.0: + resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==} /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -12240,10 +12144,6 @@ packages: engines: {node: '>=10'} dev: true - /type-fest@4.3.2: - resolution: {integrity: sha512-VpwuOgnTsQUUWi0id8Hl4/xiQ+OoaeJGe8dnFjzubJYe/lOc2/d1Qx/d3FqWR0FlpOG/cvukAXfB12A49Y4iiA==} - engines: {node: '>=16'} - /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -12337,7 +12237,6 @@ packages: /undici@6.16.0: resolution: {integrity: sha512-HQfVddOTb5PJtfLnJ1Px8bNGyIg/z7WTj1hjUSna1Itsv59Oca9JdclIU08ToNqvWWXjFLRzc9rqjnpfw5UWcQ==} engines: {node: '>=18.17'} - dev: false /unified@10.1.2: resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} @@ -12528,7 +12427,6 @@ packages: is-generator-function: 1.0.10 is-typed-array: 1.1.12 which-typed-array: 1.1.11 - dev: false /utility-types@3.10.0: resolution: {integrity: sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==} @@ -12561,6 +12459,17 @@ packages: convert-source-map: 1.9.0 dev: true + /valibot@0.41.0(typescript@5.2.2): + resolution: {integrity: sha512-igDBb8CTYr8YTQlOKgaN9nSS0Be7z+WRuaeYqGf3Cjz3aKmSnqEmYnkfVjzIuumGqfHpa3fLIvMEAfhrpqN8ng==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 5.2.2 + dev: true + /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -12630,6 +12539,27 @@ packages: - terser dev: true + /vite-node@1.6.0(@types/node@20.8.4): + resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 4.5.3(@types/node@20.8.4) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vite@4.5.3(@types/node@20.8.4): resolution: {integrity: sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -12695,12 +12625,10 @@ packages: util: 0.12.5 optionalDependencies: '@zxing/text-encoding': 0.9.0 - dev: false /web-streams-polyfill@3.2.1: resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} - dev: false /webcrypto-core@1.7.7: resolution: {integrity: sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==} @@ -12714,6 +12642,7 @@ packages: /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false /webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} @@ -12745,6 +12674,7 @@ packages: dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 + dev: false /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} From 7eb10817eac92299438b4e045ed6cf58375423c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Melissa=20Weber=20Mendon=C3=A7a?= Date: Fri, 13 Dec 2024 22:50:43 -0300 Subject: [PATCH 02/35] docs: Surface neuroglancer quickstart (#1398) Closes #1387 --- docs/_toc.yml | 2 +- docs/about.md | 6 ------ docs/cryoet_data_portal_docsite_faq.md | 4 ++-- docs/cryoet_data_portal_docsite_napari.md | 2 +- docs/cryoet_data_portal_docsite_quick_start.md | 2 +- docs/neuroglancer_quickstart.md | 6 +----- docs/tutorials.md | 10 +++++++++- 7 files changed, 15 insertions(+), 17 deletions(-) diff --git a/docs/_toc.yml b/docs/_toc.yml index 8f65b73d6..570c7bf8c 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -17,12 +17,12 @@ subtrees: - file: cryoet_data_portal_docsite_examples.md - file: cryoet_data_portal_docsite_napari.md - file: tutorial_sample_boundaries.md + - file: neuroglancer_quickstart.md - file: about.md subtrees: - entries: - file: intro_cryoet.md - file: cryoet_data_portal_docsite_data.md - file: cryoet_workflow.md - - file: neuroglancer_quickstart.md - file: cryoet_data_portal_docsite_faq.md title: "FAQ" diff --git a/docs/about.md b/docs/about.md index a6c3a9cfa..7846accf6 100644 --- a/docs/about.md +++ b/docs/about.md @@ -29,10 +29,4 @@ Guide on how the CryoET Data Portal is organized Overview of the data pipeline from acquisition to analysis ::: - -:::{grid-item-card} Neuroglancer Quick Start -:link: neuroglancer-quickstart -:link-type: ref - -Learn how to visualize tomograms and annotations in Neuroglancer :::: diff --git a/docs/cryoet_data_portal_docsite_faq.md b/docs/cryoet_data_portal_docsite_faq.md index 284d5c491..ca77ea5c7 100644 --- a/docs/cryoet_data_portal_docsite_faq.md +++ b/docs/cryoet_data_portal_docsite_faq.md @@ -71,7 +71,7 @@ In the above example, the download happened very quickly because the file was on :class: czi-faq :name: visualize-neuroglancer :collapsible: -All tomograms in the Data Portal are viewable in Neuroglancer along with their annotations. You can open a tomogram in Neuroglancer by clicking the blue `View Tomogram` button on any run page in the Portal. This will open an instance of Neuroglancer in a separate tab of your browser with the selected data along with their annotations already loaded. For more information about visualizing data with Neuroglancer, check out our [Quick Start guide](neuroglancer_quickstart) or the [documentation from Connectomics](https://connectomics.readthedocs.io/en/latest/external/neuroglancer.html#basic-usage), the team that develops Neuroglancer. +All tomograms in the Data Portal are viewable in Neuroglancer along with their annotations. You can open a tomogram in Neuroglancer by clicking the blue `View Tomogram` button on any run page in the Portal. This will open an instance of Neuroglancer in a separate tab of your browser with the selected data along with their annotations already loaded. For more information about visualizing data with Neuroglancer, check out our [Quickstart guide](neuroglancer_quickstart) or the [documentation from Connectomics](https://connectomics.readthedocs.io/en/latest/external/neuroglancer.html#basic-usage), the team that develops Neuroglancer. ::: :::{admonition} How do I use napari to visualize tomograms with their annotations? @@ -163,7 +163,7 @@ Descriptions of all terminology and metadata used in the Portal is provided [her :class: czi-faq :name: default-annotations :collapsible: -Tomograms along with all annotations from the Portal come preloaded in Neuroglancer. Some annotations may not be displayed in the canvas by default, but those annotations can be viewed by clicking any layer name with strikethrough text. Check out this [Quick Start guide](neuroglancer_quickstart) for more information on using Neuroglancer. +Tomograms along with all annotations from the Portal come preloaded in Neuroglancer. Some annotations may not be displayed in the canvas by default, but those annotations can be viewed by clicking any layer name with strikethrough text. Check out this [Quickstart guide](neuroglancer_quickstart) for more information on using Neuroglancer. There is no definitive rule for which annotations are displayed in the Neuroglancer canvas by default. The annotations are manually chosen to display as many annotations as possible without overlap or occlusion. For example, when the cytoplasm is annotated as a whole, it would occlude other annotations included within, such as protein picks. When there is a ground truth and predicted annotation, the ground truth annotation is displayed by default. Authors contributing data can specify the desired default annotations during the submission process. diff --git a/docs/cryoet_data_portal_docsite_napari.md b/docs/cryoet_data_portal_docsite_napari.md index 4c04eaabd..7b4a26e05 100644 --- a/docs/cryoet_data_portal_docsite_napari.md +++ b/docs/cryoet_data_portal_docsite_napari.md @@ -10,7 +10,7 @@ We added some extra tools and documentation to help use napari with the CryoET D Installing complex Python packages like napari can be difficult, especially as it and its dependencies evolve over time. We strongly recommend isolating your installation in an environment to manage this complexity. -If you followed the quick start guide and already created a virtual environment to install the `cryoet-data-portal` package, you *may* be able to reuse that environment for installing napari. +If you followed the quickstart guide and already created a virtual environment to install the `cryoet-data-portal` package, you *may* be able to reuse that environment for installing napari. However, many napari users and developers use the `conda` environment manager, so we recommend that here instead. Download and install [miniconda](https://docs.conda.io/en/latest/miniconda.html) and run the following commands to create and activate a conda environment. diff --git a/docs/cryoet_data_portal_docsite_quick_start.md b/docs/cryoet_data_portal_docsite_quick_start.md index f8d8391e4..e682be50f 100644 --- a/docs/cryoet_data_portal_docsite_quick_start.md +++ b/docs/cryoet_data_portal_docsite_quick_start.md @@ -3,7 +3,7 @@ hide-navigation: true --- (quick-start)= -# Quick start +# Quickstart This page provides details to help you get started using the CryoET Data Portal Client API. diff --git a/docs/neuroglancer_quickstart.md b/docs/neuroglancer_quickstart.md index 4c9dacd40..a7e5e4ddd 100644 --- a/docs/neuroglancer_quickstart.md +++ b/docs/neuroglancer_quickstart.md @@ -1,9 +1,5 @@ ---- -hide-navigation: true ---- - (neuroglancer-quickstart)= -# Neuroglancer Quick Start +# Neuroglancer Quickstart [Neuroglancer](https://connectomics.readthedocs.io/en/latest/external/neuroglancer.html#neuroglancer) is an open-source, web-based visualization tool utilized by the CryoET Data Portal for viewing tomograms and their annotations directly in the browser. Neuroglancer supports arbitrary (non axis-aligned) cross-sectional views of volumetric data and 3D meshes, which are essential features for exploring CryoET data. diff --git a/docs/tutorials.md b/docs/tutorials.md index b65231888..cfb800252 100644 --- a/docs/tutorials.md +++ b/docs/tutorials.md @@ -27,7 +27,7 @@ Short code snippets using the API :link: using-napari :link-type: ref -Quick start guide on using napari for visualizing data +Quickstart guide on using napari for visualizing data ::: :::{grid-item-card} Predicting sample boundaries @@ -35,6 +35,14 @@ Quick start guide on using napari for visualizing data :link-type: ref End to end tutorial from downloading data to analyzing tomograms +::: + +:::{grid-item-card} Neuroglancer Quickstart +:link: neuroglancer-quickstart +:link-type: ref + +Learn how to visualize tomograms and annotations in Neuroglancer +::: :::: Please start a [discussion on Github](https://github.com/chanzuckerberg/cryoet-data-portal/discussions/new/choose) if you'd like to request a tutorial. From 62c038f49dd355dae5f0ec38acdaba7e539cd3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Melissa=20Weber=20Mendon=C3=A7a?= Date: Mon, 16 Dec 2024 16:43:02 -0300 Subject: [PATCH 03/35] chore: Automate docs site deployment (#1399) Closes https://github.com/chanzuckerberg/cryoet-data-portal/issues/1388 --- .github/workflows/docsite-build-deploy.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docsite-build-deploy.yml b/.github/workflows/docsite-build-deploy.yml index 2d97f1ede..a661b4fc0 100644 --- a/.github/workflows/docsite-build-deploy.yml +++ b/.github/workflows/docsite-build-deploy.yml @@ -2,8 +2,10 @@ name: Build and Deploy Docsite on: workflow_dispatch: # Used to make post-release docfixes push: - tags-ignore: - - 'frontend-*' + branches: + - main + paths: + - 'docs/**' permissions: contents: write From 25ae0839086b4e11922e2c9545adcb4c667d51c1 Mon Sep 17 00:00:00 2001 From: dgmccart <92180364+dgmccart@users.noreply.github.com> Date: Tue, 17 Dec 2024 09:38:31 -0800 Subject: [PATCH 04/35] docs: updating figures and adding examples (#1404) --- docs/_static/img/run_download.png | Bin 227969 -> 346084 bytes docs/cryoet_data_portal_docsite_data.md | 36 +++++++++++++----------- docs/figures/depositions.png | Bin 146099 -> 150362 bytes 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/docs/_static/img/run_download.png b/docs/_static/img/run_download.png index e7b8422a30b6ea4d9c2c2ae3de0a4468640f81a9..c9a0387a55aeda2eb2e86bbf5e5e5c299bc9e6ab 100644 GIT binary patch literal 346084 zcmeFZcT`j9w?7<2WONi}Y$#QcGExVWULs;csuTe!QHls5fJ6cTLU0^KR6vQ;Pz32! zO6VjwA~BQ%X@LX?(jtTq36KaOIL;{#VyCw zl-rM-IdbR4*{6-APw|dJP z9J?;#8@oPKZ4e=x*nfSghqa3S*AW1~ZNHeye;P8odPki_{`=rf%YRP%mrnjs&%d$pe*qM8L3oRu55OHuaR8Xx z0OU2uNu?Ny$6Njq@cSj%JpjC_UHf>qFW|zjQo5Hqe)@6jo6#K!0LVV#Ndo|ObK&Cu zp51@^cz5_f#eW|IR2IDXQTYFt*E{L|f1c=SqE!{M+FIJq!t&bMSKBJ7r7{K~4{EX7 zLEN_r{IdTOE&iphc!Zh>l>?!PEic(C&P z4>c+00~OtZZ5SD`E_g7-Flg(93)!O)7xSjAy|_}e zRnBTCmKMQ+2apjnQ_ZLuD?3rZ>jy7^-?~JnPJ4DnV`9F&7q|B*V32Dg0bL(eBt!s) zT5Bf&0H^Nf002V~`?t&zwianW|F(bjd#P*NBdfLaqt4|KKd$o{|KB7*uYF1Y4n}Zk zNP*R>=D+3W`l$TBT$CA(e+(siMdt3C0ZWi_KrcNckH zTrv&Er~j~vC_qc=e-ZuQ57Avl=C{F9?|0VKn~%_}{sgr>C>I4h6`Cb)r)CzM;Ba{% zXi6xg(*Hc4WDB8?D*M0mWoSp%cHSTV^TEjWDwek@0XS7L=n>(qaPgy(aE3EJhZBTe zmJxLj5Px>|G9W(USK8ksfqyf}7DM@{t#vAB#qhmc+g3$caqC=(n%C_D|C8LQNYD>p zmG%TqvaNAY1d+*#qAH4hO9L906a}+e*whL9ZnGe z{C-*JnNzhFHF{meGGnc@36b5-TT4MsiU6dZ8}0?nvxNsDHs*ZLe()U+B$6+H0^W;M$1Lj zRtt~_9yfINbJD7TfVX?(<5>zDq<~{6x##91TH)(=BjWI$1-AB#am?a zjoLWJ6$qK?K>d8ZDvZCqDFJX({a*m1Aq0#=EotO1ob;#}Svp8K9n1GciJq9I5=Bzet|T=9>z&4}PGX;B;;1 zjs&18<$o6~3f*4&V9I25sSR8Un|h8!R+{`tWwcG0?O^++1Urlx-n3+U=O--UyQmk} zi3?g<6fT8;6Csxhc=y z44qn*j{}jX_=_%ZK7PtuNm5XXoQg=t>HV2rux ziH&WgmTCxoAWd{%jaPd~gDfEVf~=y@!IG^_Rpdo~1gN7za0vs+k-xp9tKe+eU(^nI zZZpy~^}9oeR9I_x{Vr}t(B8R4cMTC>A1pbF19Bjdpry9R$>9jHH{#sQ?>vvG)05uh zfz>Zuuhm^TC~}G$H_p7wVg3l4`E7z;!V$Zp(W3DUmxat2<~ghLx4}g0I7bN@JNiXc0Yctt(^rHwsO{>K#iW!F8t@a3oy~a&s@$WXq{*d1jxlXsI ztvp4}(;}uixzm+zWdXz!|1+50NoJUQE&oGJFjp(#;jj=YSQ{hQSA^l{xpIK6+{_sU z%{cffJffdvqVoS1QuBXy?%N7Soxf%)!Of^4g*YU+b50nN zT4pK+sh}PHow?M|9qT)-(d_+zur;BSqB@eCoyy zQGxa~Zt08l6mq*cqdi5CP{TvBBBy{}tTyuWSI+Eo3=2WUb*}ZuOfhP4(;@)8YaK!G zz48O>wSWnnHs0DY0794Mm(I{)gwa*&e^rSPU&mQ3bPh{OuzELABPI6B=4!KiCxyR! zwe|rE85zlL(3Uhe^t3a*>>`8?j4cB&OwNyPK<(62HqWJkYh|0>nhK>hXs2x>YajfO zoWCX@N031bK>W`a{})3G88*jCu$3h<#WELM;aUrJ!@1vhS`i5w`Mb=8Rbl+P&aH{; ztmM6yj2jfncEet7i*_|A8A(qGeSq8eR*V{-nG+N+{w5xKa{DUAY}Dh21JF33XIDAf zj2|?4C(*L|^xq8pBYFy%Qb+^0y}Bd+6`aSV#9Ry;b~y^65xDi8Jl)SnrXxUP{t~j4 zS5(&P6*;AB#Mh1!aFIA(Cym#+`d(aN1^fM@HcVk>MqCvn_@J=+E@pR&-p-1po2UZe zG)qad5yV$Zh2^+iIuc8D)?{f5*xL5HJ5V4Os@li<2-^9G@(-Ou({>gK^@_ZP2S&W{ z^x^M6l13DSU_X}6-1>CYyngdO@jm>^V<}kpbkk^vrQBSwW%8PS5KfVIK9ZkzCB{qh z6~bh`?(zD(9CvazS2abp?+hralUIGU7KYpYtUkq~P37*a^ts8T64_vKP43PmvJ=<_V~ah=E< z1Fva)$5Sf!7M%SJydiEq`{;a@df_?O9Dk7h*^)gu3P@f`a~lo5`^|ngij45$mI@YD zQA9T4c(e!GD+|Vaq_A^aoNnur+5NoriGgPSzOds}dJ=(iDG)3g%F5(@YWeB@b-CI} zRqa+)5+6E^iW!lulzrR5wN%)CnOVcL+EpWaKikJTm(UOzk+<$d-#VkP^=YgX9b2Pj z(6ABhp-A>)yKm(#kT+W@$E)~uPi>pcShc=ckba&*^w$Cu(}YA8eTOF0eoQkXEsKNnj0_N$|xKgIVcMfV(VFFJMgn3L7)cYd3HH1X6P#q%9fLoEskg zwZk876r%T&e+ZnqIvilWp7j|~VWD^OyUdoE-u|kZ+*{Ks^zHK$pWj=}U9=A&)m-VJO)=FU^6NoO{jwejIrrvu`> zOfGrfyB^LNB^FiZER((jU+-{W`ff*K*=ea9 zZe%n+j}--Uot86E_~e1%e{TPJPIOF}_N(6NDI~Gu$-3d{Od%mE+c;Dk``t%K;hwS? zCh=lH?<_p#3tcYTDq77QeDKv3GC&i|Nbb(qi6kBjK9Rj~qp$Lz=I`UtO|e1`w|j zt=l!>(e~|{%u5BQp>)kY>wpV#0*z2IFC9?oUcq6KOSx+f8bfs0l zzUpYA(VrZvPn#oeTNOsj9vYFoTSs$`ZN6^4Di5Ex~J%%njw>m4$iQ8#cVM2%5x>IebF zXfz<;wudss3>$qH9uMg^GW+${D3=|?h&|78 zLFUpYW15XByB+g)=2dCBi#|4Ef^pxJPGzY<(nA;Q9dfILFtISPp6doAmp_x1J0~#5 zOzXY)QJ%D16SmD@vyY{`Th{5O{3f7#sgnD~1SyU~q~Y`I&%k}QIf`bSGl~ita%(DX+aRM;z`6~_Pwku_G*v6+3iqXECJ2uS#R+;(b1{v5X_f|X%axQYvDeh#sC zHt7N6PC};)uxm*u8oZu(j${gTJk?}l_AzoGd_XC{(cU2>g#dpE#t|cqrSeh0EmU(3 zi&8ott9vIfxX@|W>_`D+R--+(&AWXv*ol39qK87%7k`bQG{uLGH6(GMPI&f2Kz=7w zgIaoM5uP*|eQ1QQUn zx^=&FQvcd@4p1mRY@$$ zc19yf0x~Ke9A=>j1UfyEf08~b5DXz_y+AwxlXpwc;`Adk`T?JL0Z!=m541ZshQ9tu zS)ror&0BArPP-?*pWX>YHL?XlKDcU^e1AHF%c`FZGa+a^1}`=#Q*)S~?2{t|OOKcr zs42*uIaFU?oL?54RHJT2j(9h}^tAORWBjhkHeKn+?eJg;_iM$C# z*5gQ|^U5oWr%b*=+^IPdu9rQ5Fx zXEE1+{Ux+vS&&DWJm9tyLC)FK%~vN}(9zfu=mF4b&E&klpz|94iB-4eJdw^heTko- z=x@Z2{orJ87Qr?anrOUuLr%SDkFaVp_gsyCbe)d0y(F)$a`+pydnpke^BvLcYJwi6(?gf!_Q&gse`uWnY!miPWRRNqAc>DsH1EF zhM4{5Xoc!z@VVQKQ{-Y^+8+wV&jwenn*;_Ey7QZ^^$rf7f!Zv03>^C_F#{C0HP4+q z@=)J}`p&O@eXm(TZ1fJ=u4hhsCw=d&yMpLQi7 zJRMSG%nPsyd!l!5{*HI_G=SJ<^IH|npzhNoH_97bcw6tg4()MZyFro>d)H=}z=de4 z)0z{d^xek>!|QF`iK&11>%Bb3s8Kz*;-ip|{z~6~s^?s$UR&$-PBVH;!j7qcZnOgN zmtF05bC}jt=OdPkD8G7VrmIQdd8%$itUeslX-+Rl3ZN4MOx7^YUvQ2*mwJ%iNe!N! zl)B$m1mg9IeY%P3?~r?5n|`dg7bY<8goB#CRMM|q?y0Qac}1VHnGY|U-dv(&m$Nnt zSR~~-OX~CnH4WQjmglkR;DI~8n>o~!WWD~I5hns^{NNztMB|#>$6qm6NHY+Bn(jBe zuG>^)J6pQDyRd0_Trzw)z1m`6|uRbFjzB693kW3~kL?p~ld7(E!aAYW4n_NUf|I*IuJ z#@=Ah45v53Q-bj6HidFQVD%8n`ScUdtYK+jihg>TTLEMkI!VcdRdkN)8|XDo2P0+9 zY>=tiiuwU7nSSky+Xj@_>(!MCf)TbpJc#bF({kQb6p&-L+6tv%2P`4mm*Y!Uxkt_v zA=TE1ZjaH)pUqK!Kbb0Xf)se#_s&a^R@EEE6;AYyP&X8UQ(8Q1_ z$&FYyRZ_QR$S3EjG{0uvTaUNS(0grC$*e#MW~Fe3nU5+H{QNr6i@MZ0pLW?kXDWud zHJP@%DMMZ9tJ!AblOYSP^zBE~x`0+9!;CKr?g^FfqVr{UO5p3mIm2G_3DmjaI3i_- z=Oz@ve7-GTnlxS$iRutcwmiZPdj?oCD6oV0)VK@;B0mqd64IUn=@Hc&jf?C_y_E5%Mle;D9 z4G+-lwiPFD6l;CO*Z9B_?+lJwA38fM)leH{fmexN>|A=mz$YadQ7$Te)-DrflD@cY z!3vl%rquaH6F6mgP+G8mg4w;;G;^H;(MaxXn)ht7 zpAA_s^vCI*jarH2kkiIz&gF0QQ_V#qI{nFGg7E&b;x-os3DDqH8854ymlnnnwmBc|&7%3!W7N)lsTc_m82s z(80)L@)3Je9rq1IhV{dgRv0A2UGG~!@K6{N(Em}=oXtu z?lx~t4w~W{YK40)M^6^Lv_{j^;K)3U&Xm7u(`5QMT8W$M*|y?(3oR~_=^~HN65c`i z@65Q<(!p+`eL-O-yQGVgnDm)-6ZrG;xN2;i2bxoz|KX`J7sGE+(jg3<8nIn{MGx13 z)^!hJH=vf5tm;X^_$f;3c+kDhKuN0S6=Www%fI4H@1zc)4XRa2MAoDjOSqHW4!ZZD zO&%`dB@fy#(nu*8`DUxS2D%xOoZt+Vwzu< zQp~SU(1qqbrW%`FKfHs-y}TA79t4bT}{_g zO;7%EVpxDBwN9Kj(1qFBX0;{5CXNRihZy$t*Y)cJfIR|x@IU{IQ{jh)`nXdO!Lp;@WHVF1{Y`>WBh8&ss;>R}nY3QwJwNkBY5+{z&4|#<+mD{yws57C-SJQ7WVU$7H z+VaG4$W_a9C)9_AoM*rwwiWeGYJ`i;Agl><|1W0~6t^+=O~Ufb*T|W>ouhEq`_4rC z;8s7F$IJ0ek17owZjv|@{VAGpR^b?K(KA3M!-iO4SC;JuBHxlxUv%?B_85!s$iYo# z`w03AC;ZzP*|t^MHJK{jh7$M1pxgG(a@7ytK%HGTGab9h6^}WH(Q~S^T!jxWmUQ+q z8mbB+id(EP!mdm~(|K0)tcK2Uq~9PV^`eI*Mb@s#h}zbtf12k|_i2P<|It1of3oM* zXpM_jMYuMUc?;=odEd?C#C+q{qm`H@u*P&HSd$05t0hs*F*RyC3(+{QN_7<#Jeh7F zwG{Z2#>MH-HK=K{V_?XczOuP25~qaT(xgqXuyCRv2%B#lR_{Ee!7NRCR49tOdR7=s z4NOsfQ7uF~VHIQ0D*Psl)l*=tv#A>3ewDgQ-sjE_c2LHIsU7_O=^YKm=c@_`4~f#e zJ>xYdyqAU;n$)?*={RpcnZ&vy4MaJVv}bz}6XN>`LW~ha`J;zI$oejxz=*u~^{YFP zva^>G|%y|bRpYdG(d_V zC9HP4dAs9foCx~BhNi^L%;&PhK1=_6egyB{XVu^0 zXY-)F>Q+EIf3(>&4ISK!+diR=%g6zNkS|=AR~J47O+o2zG*0$4`ng+g&l#Nb#gy+F z)|O9x8NtqbpKcx3O_!>^c)|((xqK~bRKXLmj9v)<;wg(C8jwZ_t=wg#JcT?8vt4j# zfI#jrhVzE?fu4QRy^^I*1CZ{}Ep9iqD`r>?yN8gXwUtX$ zVQGJ-YWAu!UM;_JTf?QWCLL(-UVcVHMt%AQWq<*W4(7R{S+xQ=2!PLw3F_z&5?T zbMJ73Er%Fh&u8vkYBJj%$D700lwjz-y&9ikZ~TlBPF$kc#Y!7XP9$&$(njXY-NxKr zN#M>m0;~Hy`hmV=pvn92YR>b#(V_zB2k27Ge#{p*qDBxW4vM%o+Vw|ANZFg~HCdeO zf$;78<~B~HVX~^ODE-F1YtE;KV-4&O84K-o*joIvQ;oDbONcEcgG12N%dDYE+%?fP zeCLxEcbeL50zvDa|4F^J{GrYS{;1ayt|sZEn#wKR_eE*s00qW(zf-+6`%09j332@& z@8}#G#^{g+hvO-n`xRb&O^toh&pr%!(=%_{v_1G`{$*RF!Y%uzI=1q}>OA1dSc8=* zRbt$v+7sum720C$@?BF+H5K{_>bNynPdGAlD{+F+ejD9!JqFltUYyc%2igjZU$06E zrEt`ko*&)NlgOJZY5oh|?E*x$Th%@SQL~x-yJg)a%F1M=YRPpIXZxuYkHgk}a_%=j z##q|#t@6BV@{2Lg;22aXq)gvW&A?^tavWC`bg-J+kk4N!KY(!QzlHbv&3;54Rg5}U z&rftZHyFL#k+Rv2L0q(?m+$+w*!JnZbqDlCg0QxlqwK$D&3khgSd^>K#$C1V@+wqF zSYdn-K2bvd?6zCN6jXXr9O6n4UU4Z4&+GG^Eez4KJsp5{VEnw2tKQ}>fAku0n#;ZH zOyJ0`5pd+f#bMU@4A)+8Lb^*|Wvnab9QAkC9fQ8UI{T2&;3xc4~-$2;96|BR7=UN}!*YtP3Q8OgME@ zq}H977~2B2<7Z@=kj$6)I^2igOy9k9Jl#WV6)&gDYGGK5fH{=B( zf3*-5<#Stq+wN=z0HE zOQ_eq8boOMvP}fe8w%H(#uNJF!onaI8xR!G{FSBy#eUyFw!d7zSP1&92*L8KzZ>Fk zfhXW)9(8!+Yz=%^XWgz7<>KTn+*Xb zX*-*^6VqPxVE0fbZr?#?kIxw}1N>RMZtexXkO_xEk|NSqDXHu3s37WkYti^bpmRXz z{4Lv`VsO3SJi-)(U<1I+e@A_`Pi6&CW2Qiz8B5Eqn3Nr5{HfrjfQpB&l zx+-s!NT{E(e%6*;&YLectlDR|fMJ?vsC_y-L5urRf6XI(VT8{f?+iEjrDALfbQ42o z#x$iNq&@5psj2a0LGFhW#*ATUKQAMX+npmsqa!kM$T@un=d0dVR!bj6TU@lBo757<3wAdTxv`(*k^^AUO~RdS-ELA;1m zuC%mZNCAc7+H9T-@Pb2-=pa)&le^LPJY6@fn|$LJ!@VY&>vVk5SQRY>{03`ifRnF) zF@DwCWQ3Lx5#Sk_)i-6AKxR#vKlNYk7(4OUHhjR^{H?I0_3Ymakjzbh@t{?@V^D%ou8e^zbz1vL>v>>D zqH&3ki8(D8{%PJwa{dXmlEbY;eF83Yh*dvta%Ux`eyU{KoJpeHTi?*p)AzR$T*I8* zBFY&9p>t;$?HY`U4T~$A7fQU2I=NQ}-hC;U8)_0;5|@$j&6)kpzXn&GjuHA?-R>FT zju`vD892!g{T+hYztB+Wsxi$UTC zo4r;KGi|m%v21qA{`5gVl}^2ADyms+|Tthhh3;x}35{NiaNJ8Plk_e6s{ z?ilYcQ1a(0KkCj177T8BXY^uT zGxfvx-FFnvWW}{nXB*c?K11HN7))Zq@~sm=GSD4HOF)(r1e6@v?p3ODOdA7FEr8Uh zE{%q#%j1X3GCTVh%3;-J0s?fgtT%=cDyOqNzcZRc6>`{AePkXMl z6<_|gT|z0;&uA$6Y0{ZTOH=xoEiF}z%(F`7n;%i47$|~xG1TweX|f+MfBdd<_Qieh_RE zRUSt_q4rnZ()XU$gr=r&%@oaAGgtW3cwJ^YkqV_8PdQmH^oTx5GW~&u&>gB&x46bM zC-P+;{~fCk&CGmNm%vPm+eOs;a(xqYFp%e!ZaNdW(yobL>trEVxj1`>U~4X z*1tVNy9U;ELutY@5wkO5i%@zm{Lw1SGi z5NR(bi11y6)*p-t-iC{Yl^|<4uns z%%q-%By2id^=a2kOz2U0Q@M?syhQ=s7Xv$^KdtfjxW0GsP@H@q=QSPPT-5LkVVd&)-;5T;3tie;CZRZ9#h9Q+8*+{9& zx0+lYU1lr=Kqgbi)u~y`YSRF3V1!qb{k>bdgRj?FRXs+tI%7dKQC^ht?GSsJ=EkI~ z7%!@@!PL9n33ROjiq7Hp{iKR_O7A`#SSeiNE=NUGAXtI9#n^ZlF13~lZg3cND7LRja?plY$_5g| z1{OY2%;#DshleKT#|^9Q&GmL?LnXgvQ+I9IiRca5fSiD15**U;ebTK2*8U{jgLwJ7~$f;+oJ=B}NO&r=f?L_|M z`HHapLaVh${VHz$bOe;9&1_pVM_T*yh(mmz7>LFIj*NN5dRY#JqT({j*OHtbTNP>o z&PU{GnjuTgNSnKA+t}xd3NALqJ#S?TGq2Zd!6rYa)@ec^7QC=!BXqLN^yZ^R5x|Vw z51t4Ny@VPBS4v$)@2w;pg?rh0hM=nPIVW^VtH*AkR2Lhq&`LKlCjV@LXWqOeVM6>%!brumh z#iGAcv%zPmtptpCnD+?R`%o1FiEDa1_GC4mjn#*_74laV!0U`apH_P!4D(T~+0tbUUh`)udql-Q^q%#rCURfPmt6qTKcryYStMEKgOz4P+|*e50A5dQ z@6X*__^yyJA;G+NU*bFlkAKT*Sb~#Ph1(@={Z_W;>X3x#z@cE3pGSt>7y@f$AF9>m zh+#BZ&~R(BA-DV0!({9HgOjVI5v9eO=*h{*&q=LTGLVb+Gf-XzR&oUurP`Sevj&hbu-w5_ir)Mq4o?E!dBlG6({d{g~Qc9UcQP+|0oE9v4@?aR-g3%^KZuZkx zkiPB8afsh9A4j5t;9H%6HjRB&r;WTLG=@VK;($EII{c4@H=KssaBF(}R}Td*J(w|G zb)XmGgNE_ODLx(6{l`4fj+es~@6QjJPGScjS8M8EgTCgzmTR^?i=XODnWsu12Tov) zbS^xI*9#KAwdf74$|ZJfbRTg!$}~OpCxjaqsPVbyV!QM=kQj>{6R0qbZDfF=Z4L*F z0HzQUnf3?0*TBxiswO?Mclcef#`S{$@D2MUni6>w3)9FOhrz+o@sfZp_+XFENuJ{z zNFTv+e|J8;iafAD)PH5_)ANZedOkTKn6lZ_+U8rf%QKc|az>&mj=G;Vur6K>7B>MUx{ zC~123$Hw!b`93O}a7~2w4CJM|g1}47Ed(m;p<8fqQz2C4Jme)w~F@O{X6K1At z#Xl@|xTKz?=9lhOFrLUFTsd3fn3(5j0#+|MY`t%fi0m!nBTt0!XX)(go5(!1vU*AU zPM&P^#Z|3hO(bU`z&@GrqhS;<1UWX;XTR^LpX1VxEmf;OS9Zfgxe^m~xujdGCn@8` zlv$H4+=H64ReN$G0~K_?7d%TZ`pFV=atm9jZzP(Zt^r;$&ZsC&OlytpcaI6WVxM&SVabd4eFlRK0fdb|dwESS z91>Mt4_-JGef+-Pt9z$PzFIsg+NV=)vF9^ENm2UcsXY>H%1IaDR|2oxKkT+A+9z-@ z#46tRMx*azrr;(}m83aFH|NDNc{~wu;YO3?s#}<#(FzQ>dh=+h20uMJO!`=NkX4@V zWYO*8u4b+07jkaHoDjK_pm0_{Vp&b#Nmkk;s$e+@lbiZJgz2ue47 zpi2800JyC#;xco<|8qDJ1rnP*;qe+JW;vlR;u0N}sP}WCmItW&mG}W@sImO8)Qtso z$s3FEcNe*v7nG2ZD+F}@_ij~=(ko?Rt@q+^AAZwk6zp8YFZybJK?rx z(XtGG?O#rs5B7hkLf0F%T&3In{zox;^?iuVhFDE|<3~(b!EtpBF&Bc_JZ+bXY^Tni z2+fv(evrc833c0pUct|5LGQZ0{HdpBXWmPKnb z?rVi>7Kgs7-7R@Ik}|@WR~1P~74%8K_J#$+?NXa+_BKp@yNHW~QAwYK?oCp^BaENr zK1E+&e=%1q`CwGr695Rw2)M9BE)u+J61e2!@T&~|dhE6scw5l}ba5}BYi(nfmi?GX zo^aXwmG$14ZK^X@xoN5s$Ypn~T;9maZ;VJDx@>AKYi`ot5}6;GvBlYnGo;mENjRwQ zu5ZsC;9UV&)XKXQ4&}Sm^ck6ThcVwzu5Tt+-Qb2v@jYrX_H%^F#I5l59*D zw>ZPwnDV7M^?_f-pf+aJW!J``$`-N z-BiNglJs|)R#^oYSWNE)anmLlP*qf%iebl@us0< z9ZjV{Zu;z?)1L<8ly1%-ro2&{8$RW7VI* zMYYD<-ejb&YIo-AnNFJro>_?ax}N%_FpI&l3AWixBB#%d#W^m|MjR+PY}8YIM4Siv zpj*MNWUBo#nA#ehvF^zHNIA8~>>cVOrK^1D;oM@6&vgnh8jC>XIc>!BQ?Qq&9&P_Q zZCR9~R=siGiAesk9>X#yQmDUMRk%vc$Q8`%f%LYF7P9VF$KJdKR7Y^CwWEZ)&~CCk z=JPr?baOX82gQa|frgOj=1bXPtxyr+-w(C8ebA{y%f5?ao|vx7%RNLt0m{(n3V#8A zh(FI+`Q7)KFjkSecy4#(tdnSY^jNQrsBf30vG-O>yx(rcx{+w>tIH(kRM*N;;oGx#(ptxtq zv*^Ifqvf?u5wMo;0jrY$PgTUsX(q?n#1(b2VPFJ3*SvCWY@f^0Bb4t_)qoQ#BT1~S z-R3NbCg9V6JV8NdlKDtFc5=w5qU{xPti$%sa;&_QLhQ6l&a92dHK78Bj^6WcFlDl3Y7&j3OkRc zu9~x7O@;EuLaTStn1@vA2wdHbgi^!NPr_wc@2ps&}u(Sotp&zprWT2|=~?0`6WR!Uf~2cySP2%Mn4@1NlG z#1iuWh0&Y-G$_5Jx%wop0%LtrW|g9{Uop1hz?T)|R)UxGSZKAKmK8=PwBOEFK5{I$YsOHBm9M z*E;zekn!G6OZUXJY0kL9_|7nL+nx(A+fh>Z!GJ{hLO))4V)e1fxAGSjEcz(xu>Ow& zMj4x3Rml)rd9COhl;h*uvRK+vIzJ(GTB zPw!Fwx)uD2^voI(It5<*1DA%qpdXkrwI1_sXxAOLeQAQk;!m@ZN@zev^%8Ofnr3NE zmp?pMqwV7!jcsh4@wavFaeUL1N6fr)YPdM=#eu_T@O_?{22+E^RI-;(udQKVM??+wQS*=U{&a zgmo4PFio^f9@0!ID_SBm2D#ZcW-4Hil-N1K#}E2kNiWCDulDCqU;G*hH|q9xLkTSN zFm_9%wwmGf?rbSH-z{r)tTvzHtF>W&YjY)RHEU*aJP@fBJzcl6>+Tz9+A=2Zsj8Qp z4QGPc>EXC!@;&!9@39f;swpX#cVaV}&)KS@Lo915*Bb*yS4W}?*H;3TLv@?qP@b4N z8D4o)&?twnB^8i_8%mbyK_fo_00yt()xthLK>-$3PDvmmKR-8YK4ISFCiB`inH#(K;< zsO;q?ATaNEx}p_I0{%lMO*fDAh$;Eq`O~hT4wP|r+pUPE43A~-aZ`~=C9_X%l!iK9 zRMS%E+st;dD?0!EUm92Br#({brdUHIcD672X`649K8O_Ol@@6g8a)j;v+;1lQHnupfHp9f2Nzv4hcd~Q-E zcK2oKWSQ!5(lh7lR_zJ2afB&%G5b`*h@dRSW@st2#J!S>SX}ilUe)$r+8T1)jd4%5 zT`A`|5%H5|noAl>B9V(Kgv~Z++Cv*B$>=<29DdnfOrmDnMAhF7pT}H(@wJ}jkjA!s zlf8FK&ZM+cU{)3CC1=e-N~-P|E#&KgI$3$TCwXv^ub5U&<=hh31*sn4e%o_qWW%b| zqbFxOYScEX$f!e`B=)3Qr^b!COX@6cqCHv(h1fIfgu)_ z+b%BNQbt#P0?398oap~%M4J4o&iw9q?hZ>A&l5gQ-sCTP4$*Q;1E=!oqd&S&P?w*( z8Q=xg#+7A+d8cpS!KUX(ti_%=u$^a<$>LW3`d~E7FmeTP5cwVcMjUL)a*G?PAf4SD z8mo(T^eqARJkoXomTq}AJxCgB;rM&L1?NBFuA6XUJCSyt;MG<^s<%NZQJCwQXN0dR z>l=Ko>$w_a7uZ=85>#_-ISgZawoj8JS`R_KUw3Q=K~+j9f8~&ao~LHC>Y4d&dk!)l zXbb%def`3*79YNCoDLUIq%GeIOSoj;8OV0nk`ea&{aWYgKQeZ$SRKn=4Uw0>fynuj5uB`^in=+}T z*skcz(%5{F0j%4iqUc>`Z{Df(us25VUXq&q1Wc{v8jdw@81#~PBJ}%Llo$9^*^vG2 zvcQ^OmqYs!?}SxLG0L|(_s9mU(mDpONo-0ht+t?T7k-x>U-c(5zzgaTbA_T`4@rTz zzJ0ipZ@fKj0t{?zy_Zq$V;#l*QMFdoDOT;V!E?+2vH9y49@oXVoHC479U4TrxAGUDu1O^>9R9u)m^fT``Dt((0J+^o+L zek7(kaT_=2Y}U};`Xbt++kS#H?}hShmm4H-jU$IfvL{BebL+1uEH=k6nmK~$wg@m+ zTd;u3u~px!vLESdtt9+E)V+69Q(3#f4G1y_iX$UUnu;*=CcW9Eqx23M5ivlJ&_WC9 zj5tG6dQB|!Djg0}4FTw3QvpIq) z-s7N`tCx5E#G#k(*5>ajRI1&^>s7$BYV$&;rde}Xi8VZEjT~iKFK~oK`G_4$=q1(^ z-XcCdIesp^j#2YcbColB#8!;Dzn1HPUh(;E+!HdJPQSLccC!?I+lG={$PqlUgqb5o zdVyTfO@y6_UDJb|$7nx&n6MpQaM*cO?XpD_H!Q1IE&ikGs`lXJ3Q0Bv$%YE;WBT?lK zJjO+1;N@n8>mKl~>{<$1VzLD9FFC~T32m>6-NN3e^$QaK5iF6!7Zje-MVE#1?VbZ# zf0$(bil#n$oO(h`w`afhz;j0jxBPZoB5AQ0D^Ne$FK0RaI576h_pIp7F#d6%ppfv{ zFrp*Voj!kFa2jY|ByWuO9eLjP_{R2~Xv?XquJOUQI}H^h&8+VaVjEwPj5rmx-+|VT zv@4Dn9q#RzvUXy<6r(nMd2u}^l>_u6uQU3mJ~}64bk<#{C6z~m3!35}nV`NuzTPRE z6<-ydH?T0w>g;q=PUp$!!dT6=t|#+b9EI7Qr(D zvyPrfcN+4O+?j#(prA+A_C42J)~+A5p!=+j`$RV)GvFz;wxOaeRZRP#S*6;x5Y)-I z=2uPbic0bM%dZopS~d|m(NLtamVEk|VY%`4hg;0N=*7{ypG@k$?30l2X)?IprQJB9 z$~Ge~3i&&7mNZvpPaCKJZ5NVZ-i=6~z{FxOO$`7m*fP=@(1 z^XNi5bD(JJ!anSvI1EyW0nI`m-rcyh^;d423C-ipaDVt1X_NL2L)3m2JHBfl^(w8V z?_MDB&K)HRFG4L7i(%iJATodsmM64&l z#H0Q9Dz0-@`peLYq&q6c()~Lv8O~h%9$Cj!8%CvT4<)19P+s+R_^@n*WQhchYD)D8 zU2}c3*j&1N-_dQq${uDO6>HTzrofB2$GHxt1IY)H03C)g5uU^YGCJ-@dNLMiTv3 z-yKFzCMvgB30Jo*(klln9lW-EHG3!;RSiSOgB3M>Zv8q~Dtu#{t551q-0y)Pl&g5N znK)2Qmo3j*v{uav2sGNy8L>Rvi&3o{wDAHu${+)(L%rm*Qj?Q<4o@Lnzyi`Gy$tD{ z9|(R4$(+pUh_b}Z;7K0RN+hi%O)J0VOR#EzsuW3(tGjpV1sq~w9a16c_Cw`Q&CFpS zv5C%domFUp)$9&f)B9d)dEDjL@x)yqDXF?^@_EKsF8$1qP#H>?S3Vi-^H85!O?z+f ztnRRO)AWKjAcz*Az~FZqq;+rB!G>}Dfi1!RPGE`}MU&+;TW)Tok3eJQ!t6MO`)4SV zbRr1JSM!Et><~Lr-V!nydnvv@O#{jOJ!!^P5G_cFz9cvlGAr4tra>LJr;ti z!&Zx7+iPN*lfGLUC$u~#IZ$E(Dh3`Roo{>T4<*%F8#~u%tR_Ywau`F&)4^Tw=tM zqlrPAaX18BT2rmAW@+)!mexjC5Nk*Y7nk(?Wy}52KFx8j2Fs|pox5+PR*Ii&WthOf zPGogkRBQzOV<`x<)>X_#twT1NgW*&^II8tT+>&#gFN@4#Zhi-RbL{>=1fCeffUt1h zWM&g<$FJ3JjCH`G|2Yf%3ny*Ko9_2+CF{;j)J@-Xs{ZpbtmDBjr+Uej*31@AHr>Qv zjkb6vP@%h)9$GV;-4=uwscc^%l)egEpYdm0WYkTsrg|zbIEs*S zV*hHyTSXxiHPK8XS^>zU@~`!A>>6#wer2aqVdrp*v?~HB#YWZz-GzUj!1EqJ->s|9 z@dit-md@J1H)D3ms^f*27Q0ziF;bR(AMWdmuSP^e7=5o$S|T%N(`3wdVB}5xpufW@5!^-J`6z{R>Nhc8Ysw#=gRYS@oNh$CaIp$ zK`DhadpI+0G6h!X8RqIm)!x_#nxqR-;}tuKqlaSCi}g%LqT+aBUBJe{>UbO2gA4> zIGy^hVy;Tx1460*&_u5DZ}_*T(i=xaa1#xUZGUZeGb-VY^tYx5Zy7Apy-vZo?~oGq zTY<}_zr6Ztj~-bb05mYL+EPZs4j&`cfj@Yta5~1DM-XFa%+4h>#<1Gvc|+DgE$iS1 zgvdo6KhFG!-4g+%Ds9H}Fo6}!YEwBCu*ClH9rBtpo1X#y!FB<@5hYWDn8eHO)TIL~ zB(>O8%Z7zc>|sB)jjqdDCT;+?i|;@G>X^F1=TuvjQy1A^%p;4)+$7G~X3-BxrdT?Y zhQ%V)v&}<6+sdk)4sFQ->^A`ebU-l2O0btvwgHahVfaN@p&uL*=y4F4V`TbG04EnSQ?Evw*?pyQ@nP!mw$XX;DqDy zzRxFhM%S@X>mJAd^FybxjA_FZwWW%HpDl|VHmTozfVVUw=IRzwwt?c@02Uce?`OAL z|F=s|pFH#E=04Eg(!y?@Yoa6LVw>n#CUSO5jk!%FvLdkWkNmg)0gTNV%S)MtR$LV` zY*T%XhKZn=9_ku$#4GKvZ$#tAe&cUtQL`gjS#&%=56Zq_3Xr27uCl3AH{ri>%)ejx zNx*Wx4t&n1Gmy4AdOtAyvuZ#NW$S5W=>8<}z#R_etR%1{g8}e+mRA65P=PSx#}m$1{8AQ@U{ORiDv$!^kt0}aSj0TI ziH4!Ix3a!qCpkGh#2El7tFqV>VBbhE04mqWo1fz0ahg4-&6)sus(XvgO^LwnC1RVU zFOs*l9?t=*?Ts{m3~JoP0p9Oh>@OU_Zo6dm_{3Mru)%oFYksEmNv4V{NFd_~P;~JB z^5of@lK*Qe;)Tw>I@SbRuLhhT<|b`sYPOe27d$-Nt2Fu_6Ts0d#_jM$2hJeC+gY@9 z)`HrG35-?fYRn`>6YBt|NhS86@_*6fbOGJ;>5#-aL`DGHhiy2V-cFunth1INj6uRy zN@mC&&~lGD!co)h4ry;>(I8mT_?8Wo2%jh6yqAC>Gh)0zjtFvc)cnnyz_VvFX~g?b z9~iuOhZQ2DfcfK&5=6sr^>5v0ARA0}(Q zl_z7hTB}(*?c@n*_~Dp0V+;TlNgSL#0AM*|!_p(t01xUdwhS0$_Qd|2+UDPz=1%>y zXLmS>WK5pmu$g7kT{a?H-J62o(C+dutZF@S2SID|`yrSSrF5Wy>D;keqY12j_`X_e1dwrW1$Zq(>n%*6C1jehTWUHBbPZ=)nqC8DzS->nbO2Of zLw7|eBAjdyEBz^CB9||n=HRGl)FsA1Sv(xUlfW0^sL5gi96jK@oE$cZKL;~7fIRW9 z1^sUkDEQ@H%l_Xlam1$svh!bl|M6q6CZLJ`=ZiMa;uZhrYaP8O|M%GidSYA^|MQI; z@>khk{J&rG_kJn+m-hbm9|{EiFMP=)cL*aH5L=PuA7+y`jh{m=BaY{X^Z{Ob3KM{0 zQA)6EWy=xl2gCi?YySO^fV#i-f9ctSkFYg1AaLx*`D~QR&Eb<2caHr_`v0ZJ_^%W2 z|B;;OnKuQ^PW`L@|KInE5dOa))&D1!-v8Y%`F-f;)=HRT?~^}_qhYVk zveIl0gaZC8Ge3XQ`}O~C+BA~%Q=8d*LNZs8TNogZNS zf{s<8A6rCx`pbDfQ^u;TNR#EQKe=7v^B36|xh=3aeG0Q>LY)9Tc{)&5FOK46gRo5A z^=bG@`$vC0BE8pv9$|e>jeAf3A_#A0G38K>I90Z3{I4ti>Q5Ea(HjXgDL4VO8-nn? zu2$mVAaMrXY5i@iHZF_>S=%FEnUvUDr{`3C(|r`LqQ}+FHQ#)aP_+3M08Y9`W4k0n z3v5%G_m95-#8ptlNDQr&INQGWHIYuXzX_DL{KpM}4fn~QfkktWB{S|i##YgUhy zY(Ex^@sXaF4O0m0ik{m+%w8{pp3=WbqAIjKB|>7?-Rb1gA!51tC8WVJ z+DGv_P%SFX;PYo|}jslGk@ zFC)LbfGo0;C7zH_PEa!5)`;kxBLy9B=w({`tHy5 zR}f$QSmB4jiX6(Hv=r>tTw?c=$4Q_5CId$@V)nYE=OpyzUHmT;vcZV0z?hUa74PI@ z_wy^6I^MTCeba`TFqG=1C9rkW5_`P2C!tHUt?bBm2y==@Q%2Nc_U2LJ{DU{eTSbrS_T7RM4j`TZjre6^^k{VX2*ksXw zAus7W-v@=E*2aeGij%-t@Kj+r7`rw({_08>SZBGW>5kW0jLGh&tMoR9{4|3X@1c05<+<^~I-uI`Z2h zI9dDg$x|-#mVnd;K9+rU>ct`ek6sBfAKp74U`=wJgs0`Ji)Ezvj{aDRnkTKe%w=@w(`E2vCFLeR;hchN@;rwsraL3Tog+sXfFCoZA%fLeI@-AFFC%7Tk!OF z!AVl08Ya?xPATUqY=0^H=7@Mh_%vFxpKRv^S_0}ME+l)MI34-AjXDMP!y@^+U(}n= ziW&;?wf$;IX(TK8zJO*x4ULA1vSU=o8V@~F&|G5zOA!jBq6X@eO1o;Pv5Q$!=A=jA zU|q32gvXLdShxoDrXI|i1d^5I^6(SFOZC7e`rfIUa929)5l6j2fQ z?{Vcwx%tyb4r=56t?U(7*ClcL`Z5gj{=?hRJdS0XfNr2|Y_+V{#Bw}gBRu^&e>>%H z-n9P>Q^EBba?@hC1>hjlh|X@OL(lqK^OWUSl5nQX?DCLqaYEv96 z%4GSmGMzFVw<)>!nEMy2xlcv{$VZ40UJ$^4`mz1HSaMatcB@p8EVg#L_7ZO|u62%5 z(-8QqQ$6ZrVgUUgezh5D1O&6c90)M1lq@NrL6rVb#!bP$(->nW>yc0+h3vWxzJ2(% zD^AmB`HoDY_G6vpHE^60&WYlu_~JUzd8~Mr&A$%s!XRLd!7Whbej}? zZ}an;kj8v}%aXNiaeIPKN;@f{-1>)^`*T``Z2x0Mv@aijhGCaU$C?U<%69V9&l}hO z&IEcm(JCj+?mdnZUL(-<8536yF*&A>HQCs&CZ3Zk{=S!)E{O4>^bW3ldJcc+?aLzD z5aE6K=5Bzs8aj9Zjro?BSFBPk)*Edi z6}R_gmO&%3Q0vM|7X|h-vT0~d>)Dvq;%q7mPwQp5%tfDhaX8kfC$QXbUC=C}C4Iq+ z8D+dqxGBkUG2Ynp>q@~hV%*<230K8gydsdw^U)LX|RG{7A|m z%4M~Z-JSXj>I}+Q&xT7)*5{v$0%XRlNBoP%eYa!pKR*p%ClB6UcD8upzNkd#oPcf8 zEeZ<_yQ9hN5wz`ofOE{WWiHwdVUU$)%Hhzk;A%xY8hoAts3bOceGwIQVn*FT9`|c?}z-8(9BpUFR8}fb9ya4Oh7_z=+ zk$>BNz;nT}^SPpJ#B3O05oOLolMvH|H)}FuirYv-VOvT+M!&-VHiVp4uzzf?DVIlL z!ETu9O7V~!6Th4XdBEy=>$)eJ-TXlhHxAoC&peVn@&Rz^S0;U+-*x9)iJ`gI6+7tj zZO!yzn3nG6f6s>e&mfPkm!Q?lc{$^ro8`K3yFL{m>uHS2;EPF_mUeJoM3ebLYIRzV;9 zNnTYh_wCN}<5m_q(m+bwTRTSX`Nur-Xg=yK!j)PQJ*v5&#Bg?zcchspQbhvN%tmsw~VX1C2q}^lpLwWJ~K9JthqsOUYe~e~uX@4_> zOEOf&Q00iE7n$QuVv`T zKLN&befDxq1J=Q-oae^3-VS?d`QHtiHW*UrJa=N&nSk#M4!Mr}E$x*tcp#HJgLxL^ z^Sln!vtQn{aql1Skb4dK@NgnM=OD}=lPopA0_+vj)f&3LhHUN8F~IR2h*@#;{Zg(9 z+3Ew&ZA^)$IDe5H>OCizVwBui?YZr=)Uf1MA#-W$L{VTB*k`ScL@Fmt0yY7X$osZe zJ4Q?>vmQU1-Ur$KOy-xf1U!L`!fJ%bqP{sId&%{&Zh6;Wre8LY2cS`jBsWZt%tEky zkElIQEk4rPi~EH}k5rWrh+FJwMcrrsQsWqHBwqpayYahT$Bl@sKgCvSjrSMRTb;dQ z!-x>WaZCQ@DDCh(AL|(_E~kO%?Ne{^*9-`c4POHu$b8Gc+{rU4=|f7vm)c(jtPJWB zjrikUn1|;6qJ8?)7r+=drJHbGL5cELoFpCZc!UV;=DHFfR^^=+`eL4&$fP#mhX?*> zI41g{_a6nawvdR@3mh+yPMX{VY@6zRZ;R-l>BAbXOUgWnE+9)xluyAI4VsT(!Xntk zbeXFC{2N|Rln_}Lz*)X@i1;bHzI6|*c#3I@iTJib*qRaf`wit#6Vxs%SX z^0d4A7S73SRO$1AriaE@1r5rVda$Q|^X(foVO!q~C?iVi+`ZgQ=;7E6$@4w7+t~() z!)0+Ke@w$~MnH6S-p2m%g*RN5!8>ic!6sF72yXWnW5D{GUAr4qwI=vQ zY-LhLUcpTv{g%&zD)KBtC2JS{#{^ZY4Pb%uZEnb```$h1SHrfkFmnAh=8#I0y+VdV z@ZUQE6M%~$iF1k1Re4IWOg~|lmHQ#bJee=%(~)29*+DR;I%I@I*nV|N$>*nE1Ngqy z-9KlA$Jl2um6_Qm--f_px^GEoTF(}mK-D|7?LnYerZM9S6Q*Myla7vN%i zznDF7U2HMNFTT_knmv&#peu6GSGCV2ML(aQGNx4mI?EXz8&C1x+ zxYnqlN9(W1uYbu8F=DjvfoZIw^xdGm_qwOc4%i#SBT^*L!bW2)>(2tbDwN@~nbr_% zfu+f%>)iIe4IhumFaTACphwxXdM@~ht=ILWufH+H<0&l{?`N*Ro}%s~l?OMj%_Jv7 zyu0HXA4im!Jc|{2%Cil19*djdcJ~6vz{ROCp3~bur%&!*zTKH>UZWgwQ7mx$3XM}z z^SRe$lWw`L-43bTm6kBBXyL)srFA1nN4bxp`*3gkp+kHcFo|G!$;Al1f?pM;53Pl* z02jqnkH06)=P0C|GQM)=%XmRoz1(x$Ykz!Tbkz>}zPJ5!N@1-5-d*mfW0ds4rv#l% z@I#_yr*nwPl9E5I<#zhWTJq!Es@O7ZNJ`~lQ0^srifKAA0S9cs6W?j|u5X`2e{hI@ z*+(A_S=+Sp82zJA1wvkbZ1;?G9+!9hde}fO{E2VzpiSHkOOY^InCD>JM11)6)Wr)F zb$B+s(zqA1P3_CrJS%izeRJ9v+iSa>-&VrBwsw8%y5&CL1~iW>LMPRKS+={iXn5NM zKYrzl5vaB5`V}zE@UY4-My?aTGGelHC%r)j3B8gZUN#2oEV|#9a*)W_(I7E*m$#{xVfTB(ZZDu;a+rbFqSheE(bbbC zbTbxI)CIoDY*}pVZaGKG;?ArLtw$!k9>phUJ`-Q%T~u0?ZC8BS0vCLGFsIm4dH>oY; zeQ}ZAe|mXs>7CV^n(rX$YiN)coI#mh3mLAB9TWrSr;!ia4tVVsh9{kq(LsTRCp5<9 zeBqPiagj<1H|KE_XM1dwPOwE`!V1(sWvsh+S5vHGMRu!2HbI3lnb=jK zuYmQm)+Qaz4)k`EuOtdvnp}k$?rm<1y+=TXV!bdGjOCqgY@9W#Ag1ci!qPIt`9(2X zcuMd~{F^2doO}9s-EiwMoU&k0N}^kj3w~4@@V!1?;=`eQjeL`(g3aU4)+Am<6qhnh zn0pI}(~dGlYty0HL78;}+G?|AXTGs@8>(*24)n%cegTCZ*BrkXAiupMesfSmR&+!J zyZ7<)#RhCt=k;M*=_oy$98eE_MBcrnq;$B9SiE6hVo#DGm2V^B=ngOk#Bi#_y7aiq z7xhgq!EWI>5+n_uK^~3tXUfqf`R}Wvh*A!+&qzx2ezH9Z1e&`*QChVfOOE=rV}?{X z3gkVVi7I2hKQ?c&Yvx270 ziMv}fPO$sl?Z~EGiL<_1&d$r*L~rWt%QoFbF$dxHq}Cyjz%&ljSeNOPYp6DPldA7j zTaP@3X;_xhcecH|$v}CzXpT#b)sbQ-3}wno0Bf~F)0el8{rjO>s{T!%Es5)K*-GU(ZyX#m*M4STJC37t)UWgGJ!f`LZ{?(4r%&?|xZ8Vla#udfM+@w{mn)Rw zK9~M2LFfisSaU@J2Npiu0yd=stu1 zmVFc{?AOc2D9kK{T?xiA46kZuxVcH7bbcAmkbukCW;JeJC&-&wTYpey%q;}g0*17y zGo&MhS>O}EIaOGL)!x?>X{V7~Ea`(#&cvXSC5iE!LS>J(q@4*Qh~hU+GOwNaKstkq ztmz#bB`e`ts8M-r7ivp0K+M+lDj=b6^J00_3XUVjjDX50riSn zEuQB3J820ndg*Ri)8omKzPH0`n-)|pVINsj+x!CTD#@5tTU(^1+**_lofP@t*UCQh z4z*p@ageYT5s5APUX9k#0@cML&9QwblG2iPqYQ?u1o~>OwWRCl7k%s5RYy;&gVR>U zr1qkXwLLr25CPEibZn$+(P!6QhEjl4Ld6*3D|Q&%1HQN9h|LL7}BrwQ8cz~KXK0+?B!#>NpO*rLQEGMc);@4 z?H6a9=ih`Nn9+?I3<+O&7Z}SmXeEYNuR}dt!yE@x>?BZ}23)~U$GHC}{*#+eIgLo* z-WE6^_%wO+L%F~)+MfsZ^`1xHG)%l5R*QXMa%9}{F{kDPVpsDL0}araQK5=NFc(bL zRJ+WWs*?>^3efZuX*TV}N{~-^O7y%WbxPJ4q7)r^B6nj>K6!MpStIuDmkI7f4A$!J zoM^B^A9m=DaO&vv*A|22;&@?8NPbll+_x3IkZ6@uwwqS_1=G|vSugh;*bKK{YFfUi+Ld#2TD{Sb&q8s5p$9#?i~9a=_!L#9$1Up!JC)aEQr zDW<}b=G`nGcYUeYt^0heCh7mcVIDWPA7HopUdD3!|CzaOmR)r%rwu zbM~HvBQckU#g=DuXuZw?qd{ zswp`B_a~8-)Xk>t4CqOH>Da0V53!Vna>lrZEl;`SKH(o$3F8SFeRHOH-gO3HFHC={u5$7Mldvnbz94>oRNNbJHQC@*9NhG5{AaCb!^Jfw_7)0qsfaPBKy=XtWyhEOlZMM4BGrv8$ zm^RGYt0juybBa|rAd(>IH@0&a$vk?0S$X91KS|@`&MYnG<9W#^puKudh@%_jo~QhI z&{}=yk0z7H{sDJyj9!YqXZJD356?7GV> zLB1|PziFnWAVNd?@qHjT$tcD+&EZmNNB>AJIFSlGgRE7zS_Xa2@Ay*@46GqK#;*690(AS-0(8T<74=sD65w8*%;>9_l7 zQ|}}vww+cR#}QAzpg<5EB`CzuVs>>&2Zd*bH(AMvPnS$BYlx*Bue;?IXH_!$JUZ`8Cok2^Pg)Fyf;*y>+FyW5l=Tphv%-;NaiZ@yQq4&G#UQWC$(Vs!{=W#mRWpqcA#ny>F@t1<(gDi2=UQBLNbbYv3Xc#E`{|{~G~zMwu;&D?=s$AQ}TI zGwts|jm4#8UghzwFgi{_Yd|T6OZHH$l5PUYi#kFE^NngaiVVvwidGogdP;d|nOANb zhovU92(Nv-40@)PmRE5kEYpf{Giv(C7<%ReOok?5xOV*h}zSLBp^eT=aE^WjW5 zP`F%ZozcS`4}sIC>3k=&zZIHa1|1m`dtS>YB=!v-AI9^whnAc4GW5Vby<5(5*Jx}$ zru}>Ia4(sj@3k#lssT;E@a*7T!fUDdv#k5yFmk4Z#g>dP{K)9NGNv3-!kb5}++3^} zNp3tsGk=?+zdu0B3>vNsv7RJ+Pm+Y7$bjz94Kd19cP8BlY+r%Z&Y#!*%RiEtJ*Shq znO+)I=_F}6M)(3VbG5bpI<PJ~p$E>#(v`&YSjIbFsc}*}~5JU`$43Yc@~ljT5f)wyNw z+zCy?j+VctXWBqSq6{PcL&J0nV@VC}CJ`j?;MYp!-z!Pl`^q`^bXOTofxGVfgl&Pl zYYkwNQi5Nv+od$4l;TXJU+4O;7Aj_I1M)zs#Gama?1NFb@_x(=GCi3`woLaF&Cl`b ze*Q-E#(w8ndbOWqn3X+Xfg#;C96RrkgvSV&hn->G8+uuD!{`d#7q&dx=92k_w$Lca z%>%76QKg2(Qq$=(eHu%Xj}Tz1)g_|{V$lu;Jt(kae9 z!7=E>isr?b8vTeu!jrvX4nh5!P=Z@kxv4#@oOr<$Ncmp?lFK~HHiZV=`8}ky;7zdd z@1eUsJ@z1Zca)@w$l$pJ%!@|lOo|IVhZN5+z@w$c^ZOPiOwMC1G4{^OPwuIx2zyRB z&vvo%R@R^Z5^(4OJ#4IN>xE9%h$9U(TI;q)#04wvea@4)W&U=m4Tu9>Alwh$ zZ^`%%&brg}9wmAD8JBg=xVSRIMXiFY4#vjjjvoOpMpk&5p$CgcaMzXe`qf#nrd{ze zT}GKwGCpNfMaADM3&`*90Bt}}Y`8KEP%$%mP69_x4HRc@SLi%aoHsKslyI-|*7WlU zRPR&hn%A?BMaIo&+vt}dcj|V6d-NqL4be>*Xr^0VbVZ6y`=?^;Z|6a1?2aL}VIn)_ z*eL@!IBN!q-yAwm2*iZ656reUasLvv_a(t^`lD3v+XF@WkfhU}?o@2L3{O`SGaPTV z97q_9$L$`L2HEh~E3|Lgw6t&SLJh~|`-nhP!*;m5<4U<-*MU9Eh9RDETYht{dnofV zYdTIPd#*dFkTi$wk9me}xy3mclGMxkwsR#e8+-xlod-=@$cvIw7sz@adZ?ZHW?MaL z?sZsXWHklms*i(iLe*;Z@Dh(R!nO;IssnXP*B%tj4HiS^P(VPq=KRlc!sa>@##rsh zXso)ikjAs8OWNiwavyy2%lT?@PiFGT*$V~N*9yEL{84u2-Ls&eC)?__VjI#&fBRi* z&qh5H9WPdQ(S<1QpH%D!(Wtt_mAhxq_~7;2#6|5p=WuiK#iNTaAOu~$JJD*XW|f2(MqA)Ix%yZ3ubv?5~shNGbQ_1O+w;yXUKV^BV8Ov z71Du2mZMp*cxPdRb^D`svJ$KoI@TW%SrbxV4zU`#+ETiLN~aD!`}b=2$5MdP-#^@xJN0J;@|YHL*P* z@l@)hDuFoGUM2kC1g#a=+o{^&dh|7=b=$KZ!glac027N3AIi` zzs|VonF#K_7IiD>%bSh48da6PEtuF**y?IEpXiuMCTqC=*N0f&@}S-DU>6Ld!MeLP zYdZ^DOFwkEl!>WDcfhXNFSQmCC}@uRUGsn2N4-cx*XwobD=RcqGj>HWpMan+)xZZ3i79R{Gs#u>%OD>PVWpPMgXXDy>($B)GA zMt=aDM|vNBew0^zplwr=7zj6k_fCNXO8akk(4t8$(v96;8<6OA>}dauk|(b}%=cL}g=O2~CDG5d)o!>w)LoBMt*qwah+n_5Skh?(*y0C0YUX2ZXt^R`(K%pE9B7Fr&rz95~7zFkpBLe@5O?GPa@h?g%{H{ zH9KRfX6&e}MdV?6tjYT3B@JgCzU?$V5qq4G$fuIZzno7yTzHmlGmZ(=r1xpad4oFT z?Yy;MYGI%tyWOn6{szMMnrLNuUIh)j{eFB(7dNJ3>D#zGnLmVwZH&TnnkR<63J9>1pUNqL-7TT_tp>0@WsDlGcoao3WXN z$%y=BozZf`gFs!1ge*K?=2#>4&bvPY+&SIToHF}I?^1?EhUEv162#+WkV?*-|JqYBg`~ zfmy`QppBO3)%@D&O~*vjUbRd*5A_4cL6d!5pak@vKv$d$C}&VZ6MJrdbURj6~3PRwcm0;)Zy4N+^E%{;rHrxjXDF-C=U< zQEH>eeysOQyqhN$*D1A=)gmykR*;iyCTyc(3g=9>-|5@=f|J?xL{ zow|l_?}!2)f5O$18aw&Nex^DMeUN)oF$eDT=9R|T{XP@A<>?Y?tM5jPs+lK|kjF!PNe69DrN$0oo*n2dypApM5+U`$ zH*=P=q9dCq64du2kY3_g!QYL(pQqCb(&LEzjHp2GGJsS8*7h$V=S0u?w%t2Rw=%Bi zxTer*qGLeN?IUOPRUEXk<8CXAb!||^e!;EoHAr#xPHRc*DqVvAmvmxjRRSRhOB66= z2{diSZr2%67^*z_t4qe?R6wnvky&Wi4Jh49s7GPi@nqhid+c1D(REL{C1-M&;Q9@Vm6!bs?S?X1^C0B?jRW)^w#)Ks0 zzV{Teh{lXt#ZA=LMgnnB;U=+4nme#;vtn=_uGPi~;1n!1^W%*!Fv@nZKMo&_Nbt9r z96lOQcVSSQ@Mx?sF8O$BT}_uhPLBXCGJyk!UQd(X+8S8H2qtOSiN8k!ZEpExY8NXm z3Hj~`lP)ys{f>mur%0z6yh z$muqjCC$c;O0|jtx{*6XbO;OO=h)ea6R?lsnA7fbxciV3;(alTbOe<6mmS76APcH} znqA^HE&KfA#LgVxz+P*d_g8*p0jH`9e|ue;zGKof0qdQL@9xFt)%P`|7o;CMd|5A! zATyVDF`wR%D+y!eu@`2GMnoEIc%WwSdBwX2u#~!;ne`pM%jw_5p#ADd)rdzidD&OpvazW(8jd9g9i8V+jveMc0gHc#u zAYU2weV`h>0ACLEzFf_wr7~EgCw*0e-hFR~J0;Y7gWZh=JYp6E)T*g$Hju#;fg3ag zvn|xB=5g`$rS<_kzmmQxbJ=$88y(p`1Jk33G0*w;S@sq zy`emYswB?iMN5SrScFB}J;C>!5XgtoEaoM+G}IOc5@yb)J~{!lwKT1Ik|0~XR(qdb zkeW0$$n&`jEVo2>n)Wg4(%)$E@|@e|ZAu+DreXV0Qv9*Wn>=ZK`ngK2<@i*vch<|z zl*w@AReJxv`&(Wmv8~$D>{q{ncTv&Gta5kbSv!h)SbblkNj@!*gh4&zq%bhr>{8)A9CeM znzgI(op4&(xr$MJ^J6!?@pCuLdHMJ&=(sT98g|FvJ|bnw1@dcKk1ldlHXfvZ!woky zQa57w3^YauwGPx9P_?5a@jKV`#x=a0V4j2)pbH|nP~hox0V1jZkKdPY=HFP}o&Uug z9Q23^B%h*%CGJ>xi>CkS4)tHsy3cc7%)KLRp%Ur$cy#7UPf;dO@TsHK62$+uuV9Z6 zP5F)R_@GM1Dm@m+`DnM!4nLXK?mTV5#W9NRA}S|dQh&L)!wTSz8PpV$-atFE2}jf1 z8Unq|T0*zdfpp$|Wl?)usOr4Ka9OwFKSg&c_ za@!#_&GvUs{nHrxRGZU0YuM0MKWQ@}&?nhNF~Q8+CopO?wFrAL3^HgkOx_0$*^U_> zvMxqb^_HKERv*vPZ6w$2E^~c7UdcT|yh=y`pPaT+c)6NC zGNdicR;p6OvQxda_>!(ADkY!FsFs{A&~T2(P$|< z6t~5if2t=0%9)PhhKO%LD)5CqSL~6U_TiHRfVdFEA2(XvPC8CAr09~$ySlQ^Q5M|j zx#fN9M$lhER7wX6qV8vaO&{wvq((VuH)0zD9S@vg?7qU%e_4d=@DYdVOkR_Q-{YIY z757?|*K*v-=ANFv_v?Y1CBGX<`1MUZULDd4Rk7$j*P)%bw04}(_#Be6d^Yi7wlK|M zvU~K(pwzqj{#a<@P`ym)5KMScc}WH54cV4*Kb(f695C%E$|`2oh52sxBIbM)>+aui zNkI$yFHMXqAN1=eEY#Jn@v9`zH^LgR*JFcBXJI4jBs8*gSmalP-)H}(;w|O&Tuha# znX`X#;52PSBt2FChVe`qF(+#MaO&dPASr>{f3p5kjQ=#|MToU}Dmyi|;Z|_0tX^*3 zLFGY`@}k#v1Z#`fuEO{drW;WZdwDSrWF;P!1m(;gKYD4Eq(_QTeDyJlu3h!A#hEkq zt_!O|Fpc9#s?l~&P~u#K=+UEY3;(L^&? zNm~)CJ8eM6j~~mHp4stNqZt;NFX9z>heh`AscFP%h!h0{`V`ct^+}^vEjhopc&QP% zy~P@Inr{#ZQyog6RY|(Ujj8w;M{fh~Rp+t&YW#V2h&&KZFeP6zsayo=_Z#qAES=S& zK-V)4GPoBUYG_iaKt-xoY}?}5%fBi{PCM~^OY>2Dxx=8bm_#B?(k{sO+trkEt|KX9 zo5emkp0%lfp^~-BsQ!P*dh>9o-}mpoL?xw=rEEzkJB932lr2K`eUccvChJ%$m3`lh z$i6Q#4932Ti5SaZl4W8VyBUn-etEw?pWpX;-@iHh;cz&Hxn9?GuFvyv5hu4gtRet};LB9}F0^xof+wBL`GLwOhuaRl>0tR? z1>XV0)YGgmYRh|_0U|V?Zro@6yOIj=5%obQ3RdRdf*a^(({dP7p3BYwuFPR6{lH|& z(8cIGCq5k^h`+mnqZQi+#CXI1dw7^tFhbJl?BonKm2!K%nr10qEYj3$vAXU}8SsrJ z*fr#(HHYuX5qTZ+ht9Ib-KpWtpIEi@$Fj#9AewtCZqnIiMN?rG!b$xzkEU8G^KGQ~ zcJp8f#ZZwYu;W?JXwD{#(g>=F9q|8a*>d47-w^$dd0rf(ll#Qw1~JRlY7a)ea1f9p+E{m zu32drKxS5cXa;oNYw5#Mdw_CT#OkMk%eyk#yEJ$SZ?Q5$!3Fk*T{DVc&8u%8u#VZR zG(NnuF<>J9VpKh|P}naUQzzp^Hye%>7I|2yw%31>7o#NSZ*BTB#l)Y(OLeso9&zG7 z%f{6?4ebV+`v#cv6MraX>^}BoTwD~6cg!}$2Z($4zhV>}v(8(NsMeHUEX*px?J0tP zw5TG>QT54VVI0Ps<}?CDfvQwo&PUC0pknkT*^ks8Q%l^mVBA-a0+81?{s?|^CdhGt zl|Q=RZbG0KUyfDCUHh~ayQ@W`FMVI8O}z6$KVGeUQbzk$(mSi{O6uEZSgC-yI2+ZM zbI6a&N)+_$1m-;AujBZU8#wkyIf6u!d~g>0^UqnQpU=yYq=~=lx2J(Bcf;`inkxVG z$X>!sM8y~AcJi}2kZH2L&b~xYKQ;0D2?;9Q9?i`{9+7_WfWr)T)MP<)1@xw$vOjE? z`uxOwSF#rz5^=i#GrwjLu{CjC@=wnIi1>TK#4I>d&FWuqr*_(SZsAyyaP~}Nu;)E7 zFG!hNE#F30I+Q-<1Wc z9EiF!@m(}np)2cM9Y_y0P_zc4aTflH-kEqyJ!OTSu>`Y*w1d&gb*YaN-_wKjuQ{Hq zDrMT71y@eZ$*>>mtde=!^*$azCc-}H^m_=;QYOxCn=r+GE0jUBg3ha&G^r>bC_+~s zPEZ$rsZ$%zUYwIPRu(Lput+zL1_2q;dhgBy{1zrm@Nx{u)%tPoMH4tFyXl>^*UBzs za8%a9Tx@x9+hi*t=S&>*YM53+Nki1*i9lfR2- z&eXKII*v>x*TW_Pds#{`q4^?o(>z?#BrG2MX6W~Vu+dsX zL%4n`A-mxWH8LiAaC{*5L_ZJ>8s2j-Z36 zPH8)>rbd2o73(Tg0qnY#{m5XD6E=`TYh?(YwvWA}S;e2Dd5~=Xm+N7D<=4PgxjLvN zyG7nQ;YXX0`LONPcyZDVUg&3waIFyh0Sb~jY!M`;N^>gj!2&hGA>*pXRJwORwyWPB zMHL^UgHnZ>=J9JtAm3Mdj0TS?>0+yUlFz8^LzOYr+dsGUcI^kMh|iTF+Pe;(&ke#? zk53i*EiPEO>`UJbl+Dc@(AXYPOD{-FnM#Bg@!7Bo{2UTT9~P0AALurk)>OF*TLvlL&=f-VHVY z1=aHZ8sniW1T!p}G!HA#F>hqwNht`3HqtW)la7w}!bk+)B7>`Bd!T%u@j7m};4G z`W-NVXFoh^m}cbO=_+iEj21lcTDdYP+8&*(^qBuDM6ob1Dr;iyLYd3Yt1yE3uEQ-Y zXcZhbQV2jGcH{kLlY;D5Y}ifqR()#m|(I~xc=C#$=x`=F58uCa}&JV*ifMK-ICYT+0=gTbT)={RL7M4TJbmM z?U(rb`+J?rhn>(_UF4lf^vrROq5n-&4msl(|12~1R8UkS;H|rwh&8O>?j~A5Z>V1o4 zbQO2UOxub}D8(>ZC&Q3J%~0PcxVfpq3DGUcANHEXs_<9ys8CvR?%Nkk# z3~V_*AW)9@x%;gVgMr)i`@Y9RQkf5&zIsztUoIyGRa}uoBw7trgg$-_Oq-50=Rw3Va9{ixz+-r zMk8&gK?oq%3j!Q>|9(Y_J{3p73}aEwfHXuJQZ}kF6-^@wlv~!=&Xxj!UlFt%NM+x( z%3);xo(-*Wseq5IPmB5v!Kamt?_BE}lh8@RZKQM4J&YrLi@taE%9hMgs=n9(QdbGD zRH)OB8*}KT?$ypPUIFffmB$cYPJ?maEPsYRXdk58>MgQ-Zt zY6PLjFg6{?l97BiLo-x!TqdA3opESJ%O^)44)ajl&Y5%JqQB9%^Ts-@UWc0)^d3-^ z!YQk6wA`Za(&dj^Dy1M&y|{BF-;?mZ1CFVMaMfp+KX{vazXmOi(Ca0l4spL`Li?;> zS1tc!9x0#BR=PP_dvRXbRRi$!kNs7WA}$5Sfn~^{P7A%O+9EX;awp({h6{EBWG!;! zoG47-$4j?7&vg^IWGAql^NY1PR_10$0sV|c-J zB%v`>Cz?jk+#qn@If=x}=zMFpU}BJ~&T*wtGdQ$bMGlY!{46Z}bv>z2v^TvmZlv)_w4fxhi+7#!%WkR8<6i zx-UPHXOZB0y|NHj|67@}x7M=Y*A>gS3|8hLR@4AC6jZrh@Z&x1`^R z7|k($x}O|6Hmu=q0*x--zJGZUaoxtX_%eo?8EC#`{P|zdwTCraZ1zLHzmBs0+WqhW zq-<{X2X&g`8qP8*ymH2xby?Bf$B%_pqzY!h=|<{>P1fl$3Rpgn+9b3hWbrK20%DLr z4E5Txxn-(L&c5c}S1(H-f+ZtRRsoyc-P>>HK9p1=qFoo|2VOv6h$70R0-Nra zyN)F>qP$?snqtD9!{>;}{qYqZ!i(t3o$<_W(?BVvH3n*0|COF`5Lrdv{$b|R(1Y=t z3_B~5PbV03y|hUQ(ux#IGnLGv*G&QTn?A>))<{-|uluKiYPDzl z?aL|~rSJAnx1gsf7A&CxCT)hl@~tWipac0d2eaw^eggtavdxvz@RNHB#oHzkM_%;k zTHIH->VZCY{M?w*_IBdQX~7k~+5D1X?vK zk%Yz9uv0GMem38}PZvWy6Phr$I_Zs5REhq(C}T%`XA8W!~&V%f(6sp*2nho<%z{uSsxIwJU9@Ny~ zPOD|YZ0an%x*~l89osEFfhEodb~E`otbBC5g)A)i0AZ1D+-vng%J5cXU5$-EuX#J9 zfMuikaBI-PckoemHSyHTBR`m(ssT)|MHpN8+SeQ!SiM}6tq(Ud?`3TM8Y=aD9JW|G z0c&>gbAm}2SwXClNxP$3VngR0R#y0|r=+b7AmY0#z`&@o|KQQ-ZENOfWu~9}KWTam zL6lg}2NbEysPi!MesBgndemAhv6vA1vnpF4i(=?N^#>L=%aI{RXtP%M@ ziox`cthV=x(z|sOc@6uc2pZ)gqkxu3F3cv6Eg@}~Q5A)peN^A)Hvv?miO_ESs{Sfb z{GkSmqOORrmF9h-Mn$n^?dWu)`@@Ou8TiQh5eT9j!hlJ2iulO*-mZMcYwP7wEEuYV z44kL4o-E%5R7B;|qIiLb$%K?eaLLTpc4qIThLNz3yTq%rZpX^PVRfIuF|v@`cb z9zCbA@4HRm+S#*Z+UKq7NKk}I@-!q-ibVIp&rKgT2 z&(Q@io16=ivbs}-D&dD2(B+2swW?-8U9E_OWgummdODtA6;x8@dB~huu$A-y1HyZ( z?SV|rcS3i!;|cYlv)Y`G(G)tdW_QG&QWESifP%%%6`D?r@PzQv!beUs>AWQap zgVl`*+xMBN?_veS?%|v>e%-nkGc6hu#XJT&P004-jl?8d7 z^=JnDqzRBBTh`Qu-*O4Bn?qA(>?A;w3^~4k|mNuuqvbUbSyYreZOiOIQY2 z3~=2_mhtECry#nzdY}Lx;ialY|03d}n7&9=^keML!C1n6BaNJyf8gjEXD!VAub;=? z!>n9T@(84OFlD5r>m~QPJqHN+NfH(9f`fQOZne-7SE{$Xr(BMzx1gr~NY`clcg$sY z$}k#k!5y&ty)+j`Q+z}m$!95UAy}@PX@doGRL9Ie7X~WV)jgE<)eerJPV5U5(rZr@ zR?-FJW*-oyi~6cJ;?b3XyQLIBQ+XtwqbX9L>&q7l{0c_5>XWk!JXUFITZ%$#cPfbH z#Y^B@N1vhoK=QPL!>A2zm?ze~w&wHArfZ1@JP!~cbTBQESX}Z(e|bKmJ~SbrE^@(q-WLy z;@-l%udc7rwU|cf5?61e(N?`zyAq=XFJ4ZcRp?s3UTEMyAWmb$7J|~(CbOUc5L0Lu%pT`t?Y9WoV2?R&sTe?)^ zi*gxqPc?)n{m5*(jp{p&chClS8f;5i$q>*!lRLu4#NcxZV35Uz; z2{`I|CV~scluOYMlIk_Ri_1zg3rMnwjp7p+L*MT-T;_7aCXM8=z#7Z(%|v|SUxB6S zL^21?5Q~y}bHl6plzR# zKt`N7Kv|jkMx5|m1{n8?3EZSl}|LL94eZ?(>B(e3z zX@nn@w}rP%?aK9a^*2XV=x)VCJiO{IP>k?e)0uLA`5$I*pPr(5DgG%fz55@BSxxZD zwkIixxH>iOOPV5Q;4KXzR_p)l4_4m^>U~C5*aAAr$JQwdYKmHl>PM!dgTL4)HwOI& zcKDUAa%q~rM5BD{~Y^ay~`wv1NexU^@BG{|4dA& z0f3D{P!^sr{haGjP}JjB3RM^M`yu1!J}vnTHrUQGc|r}Z@t!WjFDIZ3k$DFIZWFpx z6wbH{A27>k@u#$GbkI@Ox77!>n^kKlKutZ6^tx8m?crd?nHZ6Tlherei0tdXu;J2R z&R72JhV@pPk8G2gyLU^y5bYR@6kWfaxt0_DiBjT$bUl5xL}SOb{cxt)oJhCMX* zl^X7Vif_~^=HIeA{WshbP^Y-vGiNv~=iE)AcQHRs@plfY3R|yhsh#@G&un9ABm9_b zs5%ot&1xcUYLO9s39I(ce97Azr(6&qpvpcn$N$6I3hsQ#&LD%#I(<8UGX9jR4H#rR zYC4UPl<6}!JK{H|BOMoM*jS}r|FaV~{v$1DI0I#ztq!F+CDzDNj_(7MA=BW5h|E+n zfb~21O99Xe`QDMggpK)__y(T>l!K$iXTKi$iI-%|JpcD^74j{xoEED88NF*8+WZ%W z=l+)Y;o>ZS4?HHYo${#GPL6(rE4_6LIX~yK5Ovhrdl|ST&;YA5jxM(mbhqfG{|(%- z^554?+P^KBV7iUMpo2n6Pz>;9g#eZDSV&Z;PlaUMekGcrZRwP0H$|3_)$6E6i)>iG zl;=qWM92SqxpS@0oXyOspYsDi+kmk4o~jDt#&7u(F@N$^;qJIK-_{W)(2eejuP@4Y zEe+x!aSCnc6nNIZ5JD6r=7ME@@hIH6+QYPPWlJ=*_nWN)_w6@- zwTCUOp90&q9A@p!=LLY``U2hV?Qe^Fn+ro#jLA&^oYE;PBsKxyQMm4&SluW~SmLF= zvkDBcaqD~p@P(1@!xIU)vySYTm&r1WKRQUjGbV$_v))DHp$994r3ahd)A2RvY{e!Y ze3my0uc!ah6Gea0-w&3V!tI%h=Tk?97b*FX34=*AIWcq6@%37VLrIj8%OR3 z1f-Q%&*?66ko_R4zGXr&G>X{E9`ScH{;#i{14%u#e}8h}d2fkea( zLb8>hek1YN>Ir@nWJJIjmv-O5NR`%LsoDx5|LBPmBu3KQL~Peq@%^irX5a1ngQ$m~z^J6}494kIn;QkcHhq4ZZmiO+&!`meyBV*)uuJW8#g@ z^i#J2Ze3t#J|Y1tbaFtb9Fz;mIlF2~r~PRQrs$9GIoNT8WZB<+e4`<5Vi0$`E|`@2 z-AKIuS;iP=_%-w51zTi|Fd||1S}^0ApKm7KRI>4w>m{+t-xB7FrbD8(wkJQb5h5$C%=J(1 z!VYvfg)|8WRZ#pN}Y8}u<^-T)r z>w6gI)gyPO{p?P98bN0N*FFSR*e2)8zw2z}`<}k*$#IO*!J8X3abf4|7?rnnGPaxE8`G8~c^{(Tk78W2?^} zQWKovH++O2J$rLCurf*Ni+IEvF9aWzj?-CYU-OGipZqcvd_6Y-nu~O=J#~JS#k~vI zs-gGp*PLDuYGplBHA}S*qH-=*34{3DI>WgG8x9m>QqnmP?TwnU+8QEN7L(< z4deb<;87tl-9_b~<3p_&FA27wR?npYNuS`2n9-kwx+y2mKNLp_XM{0cG(ft~cSt7Y zJz=}pev!dRby9_p3%_`?D2eH!NT03X`Y`WoS@JkWaUHV6LAgaPPq{7Jfd2gMkVS`Q{1Ln@TEaD-#TO2 zcXu>-N-cgSZ&A-8~XtH*&@sh5v&J4uS)vwftPF8YY}j@Xd}~S z1h`$pd3?Z-tM~aYh-6^+Ry)adGl!w;+IJJy&+OAf3aOq?BILc-nt#y$^3O8C*W&`4 znk8s)1dC>$&HVKaPZ(QQjq+mk5Zg5A3LRS>V0oqnOok{E1rSbIr9{e6k;~tOsXmYV zUMNv*gbWY-La=}1Rnb&rsg*N(e>eU1sljRL|F7Xejiv^3w^Kch=5Q44P1y!UP$5#E zLg_@evKsuERHIt*}2OY!LOruYa{3&SemnxQ4UXStjEJVW#s6c2HR7$@W-NHZy*D_!`0cyN zk^wR8-aULRt)JNCw7*_PYia9f7*RF6mo2oQerMD23dHWW z{9g2@^~AksnFytMU+w6LxjdZfTr=_zx+;%DF1dP@ZOy)!Yn7&LvI(de+C;g|#O8N- zXYb2Tya;e>EMFJIa~M0#OjxnVTq)U=@2z61wa{&w-0{bwB)0zF2gk|AaAtHg{SPec zil6EY-ofM$dIMG(Jpoba+_lZ-IXQn;)$VSdypXFF!AxkLI^KF+*TLy`J>6H!z^k{5 zCwm%-iV;^l7`RzmA}!u_``xR=yq3KV%3!tsPK)>~7hR^DqSl00N#gkR80)-nyW!$U zyCECBC)6o~*W%5Mc6GQ-cC*p}!os>G*z46y@>xOCIpgP<53AYK(vaEt9PwT|e@3DX zLLe@sD0NY;;jet-&);ns(9A?`-*EH|Bu9Vl$nFY%9 z>1Y-)om^d#UhIu+9hAOaX^g{s`n`=>85DImk19q>*Da0{xmaV z8}k9b=Wt^SXL-36bp{nL{BTx^XyV`5A<-B<1h{0~uNPTN_v@cebb$#U510_s?snG^X90c&Op)IqHi!esxylEwU|jTAgcIJNZF#&=OP_JujbB zYFsI5X0m*+OAt#$dn*Lsy5w$eWcTjR@wNEdb_9&sGkGLjz7~yZtfpC~6SZz>w#b$i zOc})4-i&MwT3nxyhUyx#ms+g5AMS0k_6QPQDSxUSQ0m!}_1$_^`_~h;d_s7Cr#mnn zj*xGuf5jPqlXc2ik2;O4O_$W3T~T+--IiOi?4+uYxn;8mq%;)I8Llx9bFU*%3=H6s z`LDej`X76@cRQO-!xh(pIt*&*yTfnmK2NPIvQMvN!1_{KBtz`{YWe*^Rz4lYxyHM< zC%`*)9USxqu3BOWcPhaT_HK#Rl#VN>JXKb=jxL(*=U;6h>V1r>q8A;e&13zr7jgQ4>U`yfDz93krjYGEyUgi}8mf^N3}?nGAQ zO;!{4>r;dh9bteF-E<=tW5sX~I+nt?f&t+V zWb{6)D-NvN`pf8CZ02@>a(9vMC;Be*M7_LrY26VF5jrQhcN|7;TJjbPQ0}{GU!@&j zJOGvqINFld)2c%Y2iv&LL@pf6j7KY(wES~UFfuj%N!;{I@$a|eCh&Uu}@IpVK#8d7|l zCG|Y|H_Gtq_NeDwbM2UIu4#D8;C;Tyb4hdexBPdc*UzyU0=3*uhx(Qr@<%yj)5_}g zPRHkF5qohBH~H;G^?Hfve53j;suJ0Ot%f~8erjimT}xbxW#Nfe?31ZhU;U8+RjwQt zX~%WR4H}D!Oc0^L?8Y#oIg-nm!z=6Je%6sB$QOCmnhF<-fFx{b^Cy|gQj8TqRFS)B z_$bTMU)|&-or~r3mbARTu(Qak1LQ>ct@SNJpV#lHw}5`bx4S+wm7b)mgU{h8U5IPa zswy30S9td3GTJEO9%t#5Jyca^?nVAe+WMU!>+O2;igNq2oO8Pa-cL(D)9v}OKIxMF zj(l@_z}|eIku-gWi~UMjUppQAU}HLS9iYp3Cz)vLS~c{Bq7ZoKvrCcg0Q+sx z6j?;dddKS%LhnzfH!g3Y)m*Au@}9;RQFzG{(rYzRHI-vkR?`iaGyAczVpg+;b;d1w zZ@;0o-lvQp23T20*`43gXSmBE3jUJ2bqU9#o(&@O{sh;y41Kj1VFEo4zadkY^1yZln@cr$yN zF(1yIAIn&`UA{GWd-b}@KB2O;V(w~i#+5~O`l{@`>`%KXkf<&7)^kfo7wnhuBUgR1 z418S2gi;>gNQCQnSgQJZox|MUo#rIo9DM4#MEY6bHFu%Q8-jdZO-xK_HODR<(GWhl zGa+n;DW-Fvjl&`^xJ=!$IH*i0NLTK5D-3#kxW9GeO_1;A_@zIW=%CyP82pl`hfld~ z;Ob;Sc^nRPw8R;9raDXN)oRh~$2Z99IBTL?W??V6>rk1>>-S__ufWpCFe(F5R;%dT zxw+75jFp5~Ufs1#o5X2Kd^E$hZMI5%1XC9NNaQ}@M5@1fZu$ba)A|C4pL@ceh`TA4 z*Zb29+v6eHBRb*#zQKwPK9Q*JdpWwAqqphBQZ?%c?&I};{HV--{pj1A4ZerUoB2W1 z#T!dXz!bW7cfclfP(%cML5m7{UZC85oAr=)D=Wo`RdA7R4{<}X%@5QBWg_Iufx?tfJ8oyR}&!aSVV7bM3(wfE@o5 z!LN*W%R11D%`VGU)fw9{P6ZxW@bY_wseqM(rY!4%0@P)^A04`urJ!qQa~QIc6@aR~fd{U)G-_sBI;)2HAcimD1bCu%JFzfFOsTG8;u!VexCL3%!eh6x5hV%N8}jg@ zsK&A6LPZd+Z_tg=;wKhoD#oMCF<4k(`&sTq%GLpOHaqs3jG3+V5TT3{XUC16Xnr3D zdeXz@%E_HuX4bmY=pd^S=i(HV<-(ym6}YO34FoVSVlGdS+y<`n-p*eyBg!%SInV2e zhJWbLh0kT(`MW$47BcW1r)G*U_+R(U`6fVOm{Z2>G^h^Rr|~;J>9c(Ch+y}n;UZ5U zOz?jA-7!(BK32+(sLiL{G0|&9fIUxP6<>@<_hapjvS{m-M9w;4#qm@f_q-0gqDQKt zCtDiYJnBx`XOjjX>ekMLiX7}Ey?bgIdJdv<3(3Pd|B@OE>f(vSZw`B03Ng2a^R z;;hv6?>8SEAl3hR1JlRUHM25OpMwe)&ny)0ZcY7h{fK&|ue+bcfrD*j(Wtl7w(Sxo zQcl!A9Rc^O)gA^B{LzpW&?=4e;=04dvnF`Oj`31sR)P(xy2SyVUG9p|!+b6C5;pd) zZ1c~GTi0j>ibVD*#-G@~2CsMI22NC1nt$|#PxGa8dVd2dkZXcA%Z0E&GmKOy?Zr}4 z)`Y!nZ+LaZMe|Q`_m9nNX?!`VE`!7la%SFDDIL#U5???@PHa&QikO08fK7E&PT>Nv zgQV7t6JJKhaU6DlJdWDlJY%%)@v+Isi}ai|b#0vuIFVuvVUjpMRZ&a^Im=9-5+|&G z&?}HmP2_Zjr(>lVW!ZxQ)Yx8{T%??lX`i2r!-|NZ8y8YDQ>@7fVJdkXM*3Lqy)`*& zyf~!%dAX=Bhq`<+RxdiJ$LjCT>c3dGR+Mwb3}zGMCl>ojLc{b$uaW5vdvAlM@FGEP zpcRggeFVBac?UD-LBH=a;E}fASjr88<#KywJmDNbup`qh5n1M+p&Cbw>s*8k^A(cs zE7`$vI93^De*cC;l)0HsgJdGdf6dm;!0(74(aArvE;PP1L4@DpI~~tF|EQF6Bzjk* zH=enR(^&a4k~eOzzMkC$@;LjlMX%x`9n+TOlo_i`9i|_5Tm02(M|X1+YOBcKB66ZB zmC1F5bu9;oIFRdT6gwR7{rB&@ zX$eVDDo}>0x5e85&Zggw9!@u7#C&J#j>as%vJt8+Oy}NwN;v(jE8{83O%jF%7gUe6 zomvAcY-5RYUnFX<3%mzew7Ky+g7;bz260apZN4N+io?iR9@@^(O37Wz*E#_)pU6iu@x7XN$&Smo2){qg_(_!vs^yWAvcDSTr=UzTsW*_}pfe0%h~|?;Y88>8}$f z&W~rVT!kMGsH*s8x_*(9EO2~G%D|`zkHuAYuq{%(MC8Mr>772~gXtXo{!o0Z+=O|o z4Ij7uJeiVXZF=oH%VECt!55pnekVnYD$}X5AtwUwF>=*=t72EfH)I0n&+1!7ORx>P zhnTg5T_-a1c1?T4`E^O68iVcGSjRG&GNC|5C8nU{IiL6MPVIKM=CQ^KtKL8w-msdv zL|6=nN9X#u23RrTD|ne2_5uVup6qLf;CT1$hkhPJ-&nSzJj4&dc;HkakDZzPnBpF_ z+@~1c6~g~cW&c zFW~Lincz-PjUzvh(1ch}4;xI42H}x_w!7^v&##Uyw&tSSMCzA|6_9wJa9&%edWo5l zc#7O1%*ZW4d8a=%&EZMw&}@V&w#Uz_Rkyqz6R21&Av=ojwX6&c(5jY3H$ z*99e2_H(fAS>-Em)hF_hJZ4na<*S>A@9lqNEXz}Px7-$nQlO8T`(!70%XQUXzeV5+ zIre?TzD%q%%&U~cenVtd z2fPN>owxl}hdnMnyxaTOnUW-AoP6RIwV+V3H(W)simxdWv+o9b2wk(&Y{s1-q6|Rr znO0Bst%D&-49j$0^Na65FlHR1OZ-WZ+7QR>+Rw(xUiA`H=4WBnYVN3>b zL!^OAOG6UJ8{x`jQp+^~sLKoMzq=#EL=s}yy{HVFdW)N{RO849o)&On5OAeL#Hzzp zkMeUoPm5?K_0Hq^@$8vntLW;4z|U1Y!%0q*o;N1^y$KBk;iNY%VhenvS`6f@Z}YW+ zN2Vw!c=fg5{>_Tw#urAJ{$s1jZZ=&e#c;Z%DhrD|o>Nn|`|AH|6=?WMDqClJ0XqVu zW1%wGZNA@;w?((ZL49^$J~u8^_?mb8Jl&oNw-c-FB3;4lU+?9++|OzXqd#z1P{*xP z8#E1S^|3bYw#>vtG%VP?rm`t|Y$dka@16F0O&CshsX+AR;_bx-tt$lHfKWPxtwx{B zUe6y|gxu%`cjf7io_TA|Ugct@*1oDz=!n4Y-W}5)fzYJkuCnNv%3bC8JNs1cdH|h# zd>oy^MEikV>-?izqFwX1^Ba6bR@oAwVmqbHZWr-QJH67se57UF<1_zTS@g|U#k(;r zh0Q(+1Lc+~4;w4%7D1|s%&f~q>H&Mj>WUGP9hNuq{qe$ygvO_)mZOc%t71ExMDwP} zFVazv`}_l+)g_+WO--xWEt!0283f(q_MQ|2&#M}+ww)TIcq^C8!ew+un{3dGBOBc7 z=f&$oc;pQJxln;8vTc>j=lIRMF$n~uH3e@xc162@J! zFQ<8YVOo;^8(azZ1-;uQ$uOLWRjxM<$PSNlr&nT%csF&Yi$63IybyY@!*BoL;@(im z4<1B@M8f)IE;h99;d!N$C^U4zD-$x3vVXst5!&ydG*&%UVohJ$*65uGo0iE7bPghH zi}H78IDgP%jsGu!?o{KXcz&{4FGIm%e3YaOu_ zwR4A1HMj3I+Vnp~)lB@ve%!?{Q!bpuoY^z;HGq!GpAVD35Ck+R21I#TtJ;Us_56n6 z9M9Ul&HH-0=lpMJLwgNdf{LIHNu5>FzA)sK0JrzWdY_A>fBSc07V5m~o;J(4eRYZ9 zQf&0Q+D4hTu)1M`=>WYayGcr9lXEwfDvgKx{6GHiKhcmq{9y&3*qe!N?jc(xY)3Ji zcHp|@)Up1W^yWpgckXb-v}7~IUzeHerG}**_&m=^t&&np~wEWNv2! zJfCiSo!2GVEc4sf0HkbvqMy(T<0|&vVH)(hAMf&Be{rLq8Dod5h{A6z3!++pZ?14kq z9K>DDj&Jg)7;ThgnG2*4Ut{%;0l$Wd1-8wO-~In~iYtXh-}9c~TdQF54lH(@?WSeW zyEgDE?xNy+2TPqOB7%<1Co`gZ&kh#BY__{P8^Yh!P0Q=8``eBc(@k?}N%|G4=}%5` zQE?Z|g)$*gn*k=8nm6G^PuCzp*%jdn8}CCj7v`dL;=~ zZ_Dn@;QBct=p0cYbdy_^&ww~SZEUAc`v*JyZaKC9Gh4K$+>2>YK^mtt+$zB+%S&PS zP7jK|7?rzhN)QmxIOz+(WEVdN!9S;YJpFSm;Tl82pFQm_+lzxKV#dm~_rffGi~f4S z1u-LAJP7^h)h3qUQ`B48dfa#rDKgwXNPFaqvRBkvdS7I=cL|S|?W)IEZJIK}G%yJH zpqAv$m$|J2Btd~T(zGPbGVqQGg8z|a9;#>pAbvHax3OR~EdOK}#X@9T%%HsvcZChk zcS%O)xeQ9&l-`fbyPQ@uE*4Z_O!xA0avG54~cvhyU*C_*&re4E)ipfdS~v-NLeDD+=BZPI5{9jE?gsD*MfV;lQ3kn~KFG z5wZ@H&Ma;6krWsGx&vi)X8}^Bq&daf*#WFvz&!x+3lNJ9D>J=7VBe24A3fHiJda+` zeDAO+XDvVMKJy90ynf%V6^)~eMML&KUU>tZc=1vB$)^C{0CexB&LctTB6xU!ZPr^_Yl z`OTjw-|5k)||F`hAXK^Eol| z_UIQ+xyZ{Rrv}&Te;Th55!9)|o4{S7aK9HXEyf1bo}%b54ZkuY1RH{7tlzh7BOeNg z#ur)sP3Zn`R^hqtn8>3?1Ab~q18>=k##?tmC<}|s^_|9Hzd{6)#hZ@C79dqzCXK8a zu-=Qta9UIW8Mlk&&bW~Oow6_l3J6_2&4J={`1l7x2x&f75RpI8v)P<=G1caKt?Q~u zM%8^eqZ$j{1E=9`Yb45vHGgDnEFTg#G6T)$3-73^$ZGz@KasF0j?XotiZW?Yc>Q6n zC0+olJqwBSU?jFTIxSUm4LFY5zY>npo<21acTnjMStEZ@tu=5ZdWfVDgSG_u`noFtvm)GZ+Wrk+e z)_N+t!5?4DWb2q*p2!|rC3mh%Q~(8DL>ZGyyMqP5s4S2|6fq^BR~sS zM_lY&`|v3;eOg8}%Wl-4NRRJJNVvfc5A6G@c6d$DFyjXsYuHhSV_2AF`Ha=mV2^AdQ>}qwc!U9=y&;pj> z?>CTH`NL0 z>&jb7u*&|Teh_Tk<|(PuELC&N_s-i_byt0?nJL=M4zt&Z+-EfTd$*YkLHhl$Ak zD4m*s+HB;4cL}c0bxi_(MK<#Nt&}*GEWK!WK>2s+xd>9IW(^z2D^#2JTU|4PX20n$ z?x>iY&RAKU*tzLi0xgU-NYriW!aw5>x;sIjKixk`|8rKN#DL zFcNfDy?69^4CK^#j2_3LoBZ(++QH~~9=O-e9>?d;a+xub_rlS(175!s=0BlXFEUKM zm3*ze2op@8_0(3k8|And)`w+;`FBb0U{VB_l3@Z>#Lb5>4R=c>}l% z1DE3kl)4eSN)9>43S3Nke%NbFg{d=j!w$C-8JIfl3<_ zKO4Z`;l=wPyg$4Ab0F{hSl+;`8O&sE;0P?o(uo-2a(=3Zvvt27?iSjLr>&9N^zM0H zDmZ5LI(G9PvkIW{8O1%Q*rw{U6%iJRa({4I3}%HX@O`kg-LBvdc1- zv1Tb-kv(g&4k6jePS)(QWeJmAjO#dqU;%C82kQyr~B@C?&o>l_xIoL^YO=g zl$rTn*Lj`Sxg5uF3V5^5@lEDd%ZkB_fdW)x{Rpxr$xgLXPX{~d=f@;FUDxSCY%~n7 zDwk8Y6p1v|X!vk!DJB+*;n-miXN4mVDrfziu;|G82p;>7xlM*pwA@YCL`? zfDP^V)Wyn=hI%5FHsO_zM$4t;Z}WK!*A$zSu}_^AednNkV>~C?r=J|+gb76Y8Y} z@3AElC>hV~X9>-3j87K3n`}$Cm5v(0?Dm`@(}HeOe!owX(15IYpV3suk9*TeS21@2;_q*Ka# z4N5eXt2&+Ed_hh)HyQ1ItD32|F*)o@=5?oArQwVXZDCY{aIV=raz?P(|jx9#Z}1n?M`;d_&CaBx>REm z^PVJ1G%BO{PLGCm==`SaI?d`om4-Uj5^uZWMA7Y3joNCwt~= z)7Pl^thq;Ut7m2msQhX21;4U)QDc-_km5L26c?Ut|AQH;yW~!{BM23FBo(l^_+_E3 zxnh1d#M{ancNh&$9lBr=ts^x*XY^%Q*r$Ge&W>Q1jdo{&G?8Le64%kgnLk68{Ee9>T=TilAO5;?e>+X!{vG|`#XWOepXK)}hD{WgxXhQpO*s8= zDbP@Z!|6wVwlsRik=~scS^y7CTx@56>}YCs0}=SMg?ICJ&;2 zQ9OT;n&iL9brW(eR!hf*Ih~vdBgmc94}YI(Y7QBz*xc8Q5rm}1PQi1;$$gZiq=pBEanCK@Y>Uy-7tD?Ek1E0mmDFU`%aU2oChCn=?S1Rf`l&&bwff&DCN|tj?DSUpQUb z)!eVEqUK`GP|h_MG(mmgRE;ZBWMh>JnDYP9i_2RTX?MPWS}&2nJlbvfYG?TSO6wA^}US{)kCval;#JA$dj{??ySbI|z;YINp%ZI{hs z0>tWbwPx*CslyA{KW$#@mS#~c(WWe8_WGIYT$v8>%hmQ=j2>~&9}td+HH~cgEyc&i z@wWS-p|9Lm%lu}p;j%A4!D5$FGjWyfS14PWO z+f0YMDb9nvWt}9pZA3)j;zMo2{IF9?;t#c%u+gp#56C&BjNjhV?Zc@k8-6UcUxu+Z zIi`yoDI_NB>!64o7M~Z&K-Boq^KZ7wUK>q1%t}a~hSja@E!V+uahuSpC+{?UlI{VB z0J2D04rMX#NA3sjMxQ(RZcPA)PJMbpHal<20a3W{YAbCz*O%(3U2*6@p5MhU1b^eo zFxSsN!_KcyKHXjWX5$SG^s&_PCX==qQ-t_{lp=S%GDDNQa2>;kjR^6Tu<-e%2bhK* z!n!<3xpqq36sTh_|M}yuQwg%&_fE8`c2AzIZ1W%kx$La8-hBLXr7iYNIMM%T%BNae z+2pd6o?{4DOSt9)>}EjqEb~HjFJ9(KAJT-lI{-9w9y#U~#W1=g4>IrSp5<}JyiyIm z?`a%hF6E&$K=q1=X>PE8)dUMGf?M6@bI*QSIKHIQiu@v5%p^Wf z%tGuc0a>~774%$-e3(pYdPx>x3ieiP&@q$VnoTaC`A7m11pg?0&b(&X04Y~l@MNuP z^?^W}1jn<-*WF!Oyk}UC{e;*89S(P;4)tpJJ+dzxXI%KBT`zMBlGY7-uhssrTy|08 zarR_A=su8{u<6?jJ#j6wJpCaS$`NQ_7B=4l#O}*>&gHr)W_mLUKNv)w<{k2KKU;=oIfNazxb7Rfc|$2!cKVnaFR+dDO-K=^~nno;#YT4=0{$}(og9^S=Ic~j&z)2nI*!&Hv0nV{n>-q)L=1l;v%-^2{ zeg7-lQpW=By-I6OK8IZoX8Wvj5S*#ej?gr;uF*Yeq1NlAzd_P$OUudRZmTHBn!4>_ zKrn*}+m}v-gXB80db{|OT>*?m+GJw&$0b<_=P5(2)OVVOw{YUBjbleDu&dgm*{rR$;5W9Nl~^Cu9j;> zaX7m6cGsH}Qcq<{SVW8BM%emMgx=CI`4Gmh;c^s2)F{ewC^%c#JbSvSR z&7+G8s?&~xSGSD#6Jo^|_B7S{OBx6+%kj(gi065*jesUGC|$lwj|*2`Bkw+J@!d^r zdoPR2x%7oHs@J*zc?=wB&+Bi5(~^`fI*y}=-Wz&tE}Y7c$uQ*W3zAmNHG;`wtjRVT z<9f6=P;!b7_7UZtw{KTd-+g_VL#5==En#5WcV7=tC6`hyvUPj|BGMasv00YCZK@J-A?f~$@|7vJOIo;O@D7i)k@+QB+WLv3d?ybmetXf(qD&KG|gv#g;05>L#72?jk%UQ;9`! zZ|lTMM=FsQ_tRy4WP0e)=-zMckeUbGJ*}Ut$@w_qIX=uRu!3XtpHU1;^ z_1B5qKgSNPQ%GxVkLcNHlAjN9f1z8fC3fzv8(=cW0iy8_kr}P4u_NHimw^eX7?oh^ z<&Pkqm%{Qh#DKQs8Apwl(@wL1-OO{jcDb6<(euX*63&~ja5HvI+{QE!d!Zn5fVcY* z_|)N0Cf?O7t-fKDpo>B@1YL`1VN9yE#f9_9^uv_Q-^-wC-KL1Gu$@W(PkuY3X1NKm zd1^Le+u)C2_8*sO)h*^pgDsy=ifx5#0};VDA5^2EAc}mYcOM2%OIxTe@h#1gd=f@9 zyizI4hXSVK(8MrFG97{F2RKo(SL)Jm4F4*;+Qn4>nu zWt~5f2W-X7>2m1n`YTQhr;LfDwmipA5>LTx6IyYnwZeE>k6C}i2LI$Q#N>`kme5+I z+A9mBut+eh|FdkRg)H3}C4VmhBL~?aTRf0dRdA<0@|Ar}fBTg=g`;)2#{w;dB9~o( zSA552fmyS8qY@63mNeD&a8GB)mCPB@-KVWJ%G%3u3ouQW722C3W+FzUG(tdIs`mj z^cA$SUSIGe6$iUfe~JQ})6iVO;h#xL1@H_W$r0pz2)%uAY6iXO1Ee~vH3m!|!Z43} z+@whscG%u{c$HpsPR#0AZes1ON*oTXG@BkfJ-_+N8Z-6uY}`Jb3>|%^386RNtXjq+ zZkJcg2|e-Nwq7K|_gPbsVwuW8sQL;Y1L_-?>wbRB<`Tx>Fl4NQS;CnwkZ|5|{aVlA zD`T&YNYIP39s(a_4xu@WkVLG2pc9k)BB>HxodExa#pOAZLb3DGJaQV%N{^wB*wI}bi2g-h_Uf< zE~^}kBVA568O4Iv^DCO`E5iDfpFRLzDk9TG(p^6nrwfj^s~mN`Ud2);bXmu<@A@!T zu-u%a!3qnT!ZMKj>uANC-TCC!ZA3f5Yp zoT{B7rA;I31Rb(Z4Vu#Oz|0^)@6Q@3DJa5l*D69i zLl>KH_@rNXak56(Or=}Z`BZ;-aCt9XG|mk>s#utSb-JlmEYXnMsC*g|`dO#mjvk`c zZ)Ct5Utgoi6Jc$naThk@@6D^HNyJ49&_vtWzxnz?@ZwNxTUQt*m0j0Ypi|gD2{<1=RKpu zq)}+jU{kx&CzYSm0C(_+L#cN6_u$xVXj6x--HJ)FYg?WHn)8B48}9BEH80grt_7c3 zjj-{UKjuc9Hjg_Y+w$cCF-G0a7w1ytucu~Qkk9aqlerwzDA0ZR&;)Ki@3ML+CIT@x zFg%ANFCT)n9Mi2{;`@3*mvZ%1nxMIJYaj-dZPuoo-M8bAT{-l;WzKClmo{xw*l7() zScWd^eaqKu1vFk3tDi9YC!^TVmjyV1z5V%JYU@ajpR~u;A3_Wlv4X%Wff)l}|MC1Y z@xcE;pmw7@G~(i$&WjF~ik(eVk20t*H9A3uvO-u!Ab26mWgx09jZ&%;$>0IJZ`}ex zBXQ#PFemLbT2CokG95>vmXRuidk4aP-(cl)VL^KB?FT>}aNyA3SJ@&jq&BsmL8+vn z(U(pQ=HStgG`1BXvkN=EJ+f{XPlerlWZ}v2^ohgEO&wz~rzRnS~^31Ab4U11DesbpAQyU4e zzeGBr(o0`{g_^%k>#s8_%|0{oK|(mZS3twZwo@j_7=-$MO4rlQl?Lz|ETOJ)5UkMs z)~jnmKDP4>h73vjoXMeX8Z$+czJr(}kyawww+uNr_kw)pcV1Ge2_qt3 zgn>@JYhmi-6a5Tu9^7|p`eo?i;N!P7&O2T5c-b4`B#32!Yni9PwU$+*#N*muFMnK? z?kmnh#j^>bqu>^@c38hAMZ>k1nJ213!IRs{RQ} z$kk>slsL56qJm%ZD44N6EsZ@~F0k9pLBJ!A!^Cqh<7~3)wrkps0r|enkrVRn+8z9n zXP>qAsEL-(!Y)Yfhj}ooG5j7A*xE{3+(lPU0 zwtPt9_!^H6H`a`I8|Qu%rz`1fD@(%XPt~;KYn7j2SD&P!;MlXcfFfwl_&zmd^ZqhE z9Dt7pc~0D`{AlQZMOeJAy)(o@F1{YV7LSzzGXHMpxev{{$U#Wv)_vTO4zNQ*9oGL! z`TyD_d)4`>IE1M>%9d&f?{1Y8O_RpO^4k1DfrgAAGt+od(2Kpi5w7zH+`{z>H2nN!Hr03X>Xia}e3$ zpN_oI9=hOj$Q#IJ|TWzNvQK}j* zEv!4efKE%>F5wuS1GY69U_#M^A(S(M@T~rknQlJEYzKKgd7rOYedgPt?8XD1_ZN~FS%I;LZ z#qL};yLB}~uwwRN=$kF1rIy{$vQKe0s;4#izCP0$Jw7QGi6@b6199cj!Iph5C%3+Yk^|GP#pBx z@&MK8EqqR~a1Uu)N9K}&v?$DzQAlGjJ%q%%SqZr{S?^)3$H0*4pGsy2CuJ$y2{J$lv=|$?&Tw@;u$V z>t13Ze8WFXd>bWq;<_#E+0FGv>2M6-pIrTwi<0Urf>V}h(Osv&{5Sr{NljB_{xd3 zE{wlp@)k(?=ckLGGs4VRP;o3KC&R#HE?7E~(O#qLcBW4p(lzhH{P+LeT50g!T$}}h zX1^aUe*JT{@&7(eJM_PMQ(Ql{&&Okk0M*U%vOCKKDtlVBv$&7WApf88eIjp2H6?!rR*n}Wx8p!7$vyk-Qite z+KP!r-X)L-@5lQkABXp>O*Y+$&r_^Jh((jmS}jJ}Tbj;tz?8nfo~O2Hk8gGB=U4R1 zj1R8-(<@HZ)WBZ|?7wW_xchgO&B93H>-Yhn&C>5-e`#u5V^^^F_^rt^t&M(IKC+8M z51`KDsRnyKl67DFoFCz%Qw)d#h~bnU@z~xp4Ox0`rYHko-5B#&lOIymdI9J$Dy%_% zPN?&`X{YqwDPV1-9zW}>RlMt+zxi+^a8|}|3+)5k(`=H+Of1<$!%MhZgoModOUBQIR~kzT|Xj`*J%qA(Z%t_-EOPrVlD>w z98L^-^>448Ka*F_IvMcp`0pj~_q(b~b^33sD?DC|{X3j^c80b}UQ#(!khb3y*kXpY zgu6YT06s+N*^AJp!7nbPa;gQ-kVe(oc<*bKwzR)89IJC2GXsTM)STV!wW*%^0?eBV zVz4oSrr%iUY72Tn-S>`k@2>0`Cwu~YrNP4G_6}qnQnpjkXE`3ou*y31#-I27;3ku| zVF#CjZ_CNcIro98>JQg;lvAKUW)&6bR z>Xr2p3`4LkE)c{(h&Q-tS|sn2^q0TdELX|+uG7u}GZ~Dtq&=PYGZcF`F42X%t_&j> z`g%C7&G>D8nFVr4v|AjD^iHQ6R4r`AXodoip?Q!E@`)6p3uXuEyqga!Knpr5PD=bb zT#B6eWdLzV;G9e!p0hm!qX*h}Q&uxgC)Ke@bf2pp4>-Buw?MK?@jmoWH@U-$?SY&+ zsrMRN6hWLoPr^ShHvf{L0L9C)!+mY0^#`TWXxgC-psOp0(>!+1CO%g-sjq@pQ{yI| zKa!VI&K;SQq)00JN^!p%kkqd`%62tudN1S=>C-iCA@km8qBv$rHJ+9KRGS9_6my@9 zG1EOE-x1u&mJxS5+>lmKn!aN6ZzuBCiY2#H59CDkUe=YX{K}#~p%3vTxnL-7a4)yU zyC1vR?V-_dK(k8MzM_RuPIxdb7tw1)dXL)Nh3}C-Qr-3^qax$EKnhD*7hveyJsaA7 zS{fFq+7AHE>0TZe`v6yjo$?FiZm2%FeAVhFKn3py9hCe!h2~>F*ySasP%B!2K`d;z zpTFP;kXWzWXOuK}ENf$TZ&)J2Zg@rGk$d1koJ|77c5DsNR;2tzEN|%hDgoNr`=!#j z&&R2U%zSMAqbpQZ{^X-CJW{P6XEzRy?gGm_La1xc@nbbljUR`tD9Sq63`~=!z6jvK z7M3xit7PUHMvKX5KOyU3b3NP6=R1_sFTlG#2!uS}lf(XrWyw?i?^WUolVF$>4GoP6 z_YzVF>Sd}^m!UWhe?@?0rg$EFOZ6L@0-%LH)re(X$P?je<<}vUZZUxndf^Et38CI- zX_b&DHQY3%Dd}x@E-yWx8+tn5^J>v8YxC)eIaO|?8(Hq1t^QZQaNj!WfHS%Lv~CY7 zqA`ECRo&Gr6$tts2YUNP3y8g41kg*WevtdO(%{jUJO_@e`=U2tfh*+^;%i|+ZUM}0 z%XcnflhMYz&B+6o19(cWf<=sBn73bkN=z2&?}DNg@S>&gksA~l!z*-iDJTd3yC2j; z8@3KC9HiLHlc! z{&=@aCqQHa^d_bTQ`FB(UlFJoBYv~ZIQke$2~nx~($dSF83{{&Z75=_?_!lW{Bb;L zqs_iVJ;!M*b3PQ&q<9Z_pP|yCtHZBjLlLxnLRTE_K{p!i5JYnj?#+H?`cxqw0I{c) zYO@c@cITU6{s*-t#b5`;gij?k{Z87+cbK){fiQ-*ni3bg(hsN+)D*m=SzVGr zlnGdW)7*ZGtH{GNggX%+$UI|JT7Exq@aEHgdyw9DzvaG^Tj+HiR= zYCOhF=-Lys?Nwbs`(t|@93aWy2l(ujYNB6)J5tg`+HJnaihjTO{nh?gm`lZE67Fg$ z-U3W#g%~NH^kQbZmqeM46%(kj-Go|&(7a?EjW?F*o{fp}cZz;M>T0~Vu`9ihW?>FG zzDrVi_>7=fP?2Q}qpme)(Hw!dX`oy8r>7mf(J@ue%L$Y4@4rO)E{W)oT>e}mqGt$ z?H8S2Nx|f;P)*u5olD%`vrb3LP0%xxdOzI%3}*MSq{Wdxx|~3Vv*RcW{vHEtmqxf! z@=^$(MKEK~7Ef-pRdq7zLyHxu!MCiZKs)%}LOa;SvP@Kac(#}8JWB)iU7(VX6E+SW zzkrcLKWD8+ecR!7XcD`1%W!|fiV9au*iT#9B2zP-lN|lzqta=(iA+WBl0_k`hvO|$ zz~Z;9xRo;g_exH~ zj6or!Wh7S-A7Qx?8U zsB)C#KatSMQrvtWx%0Kgx0?A^I;8rx*A2@YxrPfF`k@jZL|v=}86Wonu?hpwN-sr9 zV7GR#E`lhExfeFZ+XZm17@vj49{@txc+AKU68vIcd%- zLy;iN)ErR>>BgC5n-dCxw~+<}P1t5xtmA+0^APTfe2T1yry?~yS-RcF$C1Rf4;F69 z8VRHTa6bE$FIprjxQcGn8@NA5+)LawoW56oXxeNXk0TZO12Od3=^BaLI<%0l*sH0S zq+mPk6)~|WD~H+Mo<_S|yEd5(hsR{9<(dczywsHvI{&W1G;35G|LIlFwYQIWqbaT2 z=UwUGte(08I7S>;foZU~0k6`nT|p23vN_%=qtX}9gZbil>dY_kaJTt5azjjF>+!Rr zE~&+rQO5gw@)_PW2DO$Y->x){n#+iLnDW;3<;{5Bx=nh_AzXxfWHf`I047$FEo!q* za%q-8%G6C;{r2CwXZf8-28);|&}Uux*6i)R9T=<#15`2=q!64-n?VO%K4`aDunV&# z9VZ9R{jnTy)&20wc|dkNZkP%e-c9Okdz*nh4#onH$3Bs?rl#~K`BxObU9bAU09KME z+KNY7u&y_#;lSR&h1K`^0$cym>B9K;YTQ_5WojNPaECuiRg&Ecl!>Umh84RqB_j0) zuV`)e*06P&z#|d%zs2GHK8%2+)zXp7lO}{Q8$8g&%ttR|RihaCrdER=U3du+D-;w? z8}^~pxf~3!qMfSlCyyWj(9i;(xM*~o`E|m2b*60UuL_)l}nPyZ?9T*)`hj5bk)a)zpo z&1G{%cLy7t07C!wH!$IbNU8f~G@xFa`!x7LU`Ax71GYpOo`tgd?jj@pfTpNhJ9!hh zuoq@VGh|f!GpZh%csfV8ncw6tujZpaaX7w%jdyk@Xidqe$W_mLzWDZ+w#EG{mvwrD z9J)e9wew3ifg3RZk{BYOI*+;A*RIpgtl-rR1aVCri3PdbPWcQc!G0&=9%hqN=DiEU z{gjS5p5sBTq+l_Oc%uH@bsaJI>4k)MUmkxD}U@l(hPT!uk@_0xmBA{xPwOT!R}E^E%S z{6JvM2N4%?4SGX!g2{HA0g}iCqTKP;*PBNike6GKCtFBfI%}Fq_|}Ild#Lb`M^rlAYh?orR2oKjMDO zMYsoOCz`|-nCh2LP00-wS35!bg-4zzD_|GYBZUKq)nUEP8a=ad>(g+OtlW_EckmKP zF(OELcHB*-ofPG0@io0|UB&BZQb(r3jkxU~>=wp53(c zG+h&yh-;=@V>cXlI3j%STUU%s~xFqr}@q@SesnGb|nW}_i$H+ z@}-CFReHVApCNpZm36@+dk34E)(>cL>qK!r)KjJ+MIP!T&%Q?Cs95p5Tvi#c^&v*3 zEuigX7hj{bz|w6bXq_sYyi1>I?SG#YSFULn-KcvN?=#yKl{U#9FE|;pJ=`~2J-w%} zgj;;aT0E~qJ=01MAnG=1Mxemi&Cow6gXzP=g<$X8?Wm9o7p`n16#|Pj>War%& zndv4wZO^v|r=D|J8h(p(icvo(xEeWiVK#5IL=~=K105(DA$U8@&o}~kpn{T3iz5yl zm^n$&VSBUoBDO(`G5%lM`1gyS7QWVbk0flZF81|;Y(NxAOg>3;i+q{f40IZ zz#W>q-=W^KgQnghDlSBg37X+@Co1IxrQz6t@S$PyxXH#ob+D7%5BeinZHPk(g92Ae zqpk~?T7DdPY%*~#s>UJchI_K-EM)bqKE%UOv*$w0`EHtYJr(AWl~iu_5y<>J%wZ%7 z)#;HWX$9bMg;19F>S|c^B~fNH8?eso$-(L1uL)E9B+rBU?)UPHW+(5SeKsNG2g?G~ z*gJsPvRF*!YOdH*nupSDm~C825+>SVDP;dhJl8Wt(g3}bXOj)m!k2S*nyB`x&ow8w zH%$^rE$m~h_Iu_1S@+DFp2IhQ>fOjppG86gaS2q10)32atX*OClIbrE1OQ?W<>;Cx z5BUTqU9}z!P&GjP_SWykFKkRwY1+r8@yHSA%kh1<>+@U`9gi2DZ%oJ=Ee_k}FL)86 z*dKTMmumfo%LF#7a4a+ErmuxVr*gOQc|}%ZPgxa>(RMv~^l*)(*a3 z%hvVs;(Gk$u_KDlI)}dnc^{F`cIR7aHO{vuTe6i)E#PfuHA@3DcyPU*4BYaC3~C}` zt;Enm#7W$l>?-v@t@G#WQs2Ve)HLkhVeISEHG0xlx23TR^o3s25EKn*A7-cc`i&&p zKDf?xQ{}>+wxajV_9yOoucctxptgC`!Nz+M{kePDME5f|fF5H0P8Sw&eKklZ4$OEr zT`f6DN!ekkH~GrK{XisVU$hh*pMs=14T%5KfstwhD{C~K4a%K;fjEC8+pmt;1n9(9 zNlgA4+5P>mxhJ(pX^o5PU(JNnFnXt7VZ%QFZr~&Mp&H2ENy$m@*dLGr`-H>|QR&*t zPE$R3d#S)_6k}^zeX&lM-T|H{CvDO8#5I5Y ztf#*6M#J)t9Gl%j)BYDhAUE;09Q3QYvNtD61FF;RUmG1-<;srkc_$En^$z-w!fb8G;(Rflgw{Uw8BHqnrH0Jsp_%@uc8Fex}`B< z>S{qAlG9^e{!aZ^GaoHTQSTWWBNi3f7WMu*gxE zeyOM9=??-BavR6(0u9%^i8!DLGh;kZ^}kn*h>lHKiYHN)G*uXl#I@P4HRuwM!Lr0hZ;D4hk*5w0M1kNXnxLPW-y@rj;wl^+W(Vg`@dj74G#qhLDyPz!P1+%t6~Cy*k<#?a>0T zF{9~pJ$3uzF%MJILioiq?DVev45^_h-=1j;4D@FB0luB|i6xfOI0}hK5tFLmEVD`a zo^mv9YGdRc5>9NCxY)~dF)yRZiS=VS{t-$X^=tcs-1{3WQ(E2(Hz;IaOSCakKe7+6 z;8{7cb#s+s^G|os4T}K?v{petr&d}#HiPXPVnT={zF2kbh~7EC=| zn$drAmt4WZVF)u^<4rcGXNW>7vb$v?y~m~j%|R^SDnFAtxj^w&KBc*0Fd;S7tm;$a z;+BGQlSpJpHH+mHZfdBYfdZ8#Vg`9Yk>Vj z(cMIgOk?cBKNd+}YpB#}YwCf&pMboVLza?T94U!POPzBiGa`IzsyB|KHU9f~{%v=K zaMGEM)f%$wR43>61NvKEnhq9)Vi0E{z*9OVyIGXVP{t>>CG($fNphy;j$u2yvcRhw zK&wn_40@$gIP5^#>mI+8RTA>&NR*FD=_>TBXoF@S63roAtev}-nv%vJV$>(KeZUhB zAfR-N%;5f(g&1GA-1%cf*oJ7GdED!-@$O1tR{LgH(w7@5UHSR77#(;~cY=B;%`fMU z;e}tqn;JM$Pd-}^<^7cA5k~?Er2d~j_E?}=XG5ox{Z)m|QT87b%!YmQL{IDqL!K>uH$!^jqxW}@CYqikR zodXgCzjVgYlD=V$BzLM|3GK811w{!beA*+$f>tKLg)z^bEE35n*Zmlg18^5S#wKtD zd=w#D2M7jo`atv#N!dZwtxIwZELLq#{6kwbVsjDC)2(lZK3S`Yi3iW?zI4TiBuhVJ z#hN-wlb&aiDhu7^UA@GUc?dv}0U@uF3rkV^;M;TWFOh}9J^$;Gfr<$Iw4vRYvg8Fo z!}`YB3bWPqyHV2ne<vWcWZdeq?m-EMDkg zC6wqD1%oqPEK?xo&(lW%V}!l7eQ}a0Z1G6n_3s_OG$nVgEj z)W||-7EMJ0NScjKxO-^={QbFdF6n>Ewg1BgCWV0@&5_9Bt=f4DbTje=SujKTyl(hC zV6*~7>5O-lJPjEOi2lbZAf90iOH=0~XIif}2HmZ|>Z#qO3HQd8*I&(yl#c;QsGeyg zO=^+l;O)yaO6*+#;~)*M=0(1+?nSOwbxcZVQpK+P@v$q1hkI20@KYl|`f8?z=h1|| z9q6{xB+FkL+#!|NPI4Pn8MOpNC%1uefG?sM?DXo;U)MeOSw2nOMkY3?of@Ju2#Ya7 zZUB9B^b5Ml*tYFXOO{g~KS@a)9;+_`Q5CX*UiV2<7pxn>xGn7g`wdR`@H3S>DGyH1y^n~{MJ zw5IBQ_hxSAEcU zc88XOFR1Dq8K+f-F^^)XNiC}joWk>(*_d9>9hK#e4em?7pb;mz$nVABHO8LMeoLWp zkD+{q>mktw14#|CFSJ`L~|w zKm17@&@Qatm}id(=LSRF9&h`SdnSWK+4aJN;$jA(F|b1?CgsaPmp67Fgd%HMF>X~T z2nTJbV5rD?-Xf{(YTDvc$Mmvehn|&`f-j24giq3@Dm1lh_Dhd!uQQ@!kmvKnbv=qN zA$<8Y&U1ELbzgv`(--Pe&9W!Y1A`OL@N!G6ch+;<`S&q9gLdrNG{L;PuVO@ewgv0+ zY#olO%v0xVxgI09C)-vt{iZsy+Fu*O`drTMuX}bo<0b#Jlb)OhG?GlH$p7(B|MVV+ z#Q}F0Tc00CLD0R>v8=gNB6iH3k6a9>l1PaQ-1!~qp3Tvy&a&{RgT`hGKAxg zJG*w6SnKI02gGKDtTTdlrPPjO9tiH21-L`)rGEqG{(H^g?ebSzz5^&AQ&I?mo+<8>4LI3f z8X<(gC?k+&39anT06?XGV4ME)JCtL9zh|d-2L?v#G?gi^V_#thEw24zk^cFCg~+ck~EBGy9v+p|M-hqrgIOsf`KFizAxCp+6GK7YDAwLZDLAo>RLfX zc`e10zZ~m7Kjimof8btPA}N>JlysAds3S80K$lMtcCcK~Ta`!}>$6XgCN#g7e7-tv zjE4Da*#U&qG>a5N*1ASz+8!WTH6Op)7j1EsOwnr%z-Ux4esV{s8qwJ3j3yJ>P6L>B zI^BVe`nF`H&S(@Ba|1-@Ti){G{AT;6kJYO4goHvm z9bIR%JZsyZg$NH68qBq6=Q=febJt}8;9a)qQFO9ec_;s%pwl2zWCNvt@WAPNnDCs= z_a>q7>76y9(#nwv`;0*#20^pcKR9W-rnXw0NUe;&XX(AE(NbBNrL7I7f4j~ zK%?;IiBYoX8o)q+YKi>^n!e}oTn*?*E%{ zUyIs<_0|&RNKNkFepE%N%V z#{ZA?BSk&digIVqYD~60`}sf&6lC!NRK*VZ4y0s){2$3rg|1u`saYi*e#1a*nlKBK z@i>tWAv&ZkYS}32`TQH;I4Oi$R81QjvB%t)d}$F1^6YWj2kJvD zdJTG9QERP2>fzffMZtg?@`il&_3t;j^-Ie@A1#gtcWjLAO9Wd17#SV$V}+J@F!aGU zBv_{dInwP@amfbY_^-dUaa&d`&9=*(nr?tE_2HtCtFZ+#YehTR2piRIa_d_WoAU?# zVvVriyF|l^sH#M}_r_-~+5n~1(nGaC(I>MmF`0$}5r`Ka3)>^z=dtwGbsp3&=ZucB z-Hh?6DFTwv#da4wFhv>u99rqihKSI?ZNvnI7ei`)yu(P z4W*~*l^9B~D7fIqd!(e9eE8?d@gaJ~9wj1lV|VP3&^E&t@giz;N0)7dY5OOfxr6zB z?i7UM6c03)ztoIBVU1oeI+e1Naz8llJq2%cGTQ}O#N72M{w3n9DzVOv6G*X`TLC2h zS9I{WR%@RS6Fu!(vP43s1gh?^1e;!03u`S4yZV1$fW#dDJn#FMYn~(GLNhRQT2Pj? zgPJpsgA?5?0yNvrVn$=DVi9MeV%mdaEXX<;2B`W#&}Q}=gHi?(z<4=ICzRKwojMQF z(68&Se&(E<*x+LAJtl`C-3rk$5*05A4>UpDB(*N0laEu;_Ojfa<|+qba%NN%QBn^s zDS7~{%^I!ryA7?c0($41Z%>ufImJ-2W?sNW;xpf0LXJw*ln)|x@lp?Sn+c<-EbvoP zEf>>y;fF}?X-|+##w7CSNHf^!KX>(CPDC0dpW+`JwI2$iMYa<{{bhi=c;Ap|nGTJ5 zd}2J_H)UfD=w|1DLBdz|UVv0fQhs6F+c*`NID+MY(Q}iJ3~hfY_QMMU$dn zUaQZsp%kA!q+df}joEyx{rUkHN~?eSMt4_Z&`tL-3GOc5$`E)_#nHUA37pTm_Sk(- zLpvFD&^M=8f$lN%V-+ z$$$eK4&J*4D7>~i(%W}%`a>COsf|lLXPUF+?x=Ab*VdU8G?$ZHY9O-Qr7T7@rqw~t z=1Vs(NnXCGyKlP>RB`N<*6< zsvbt}*KmZ;hj8_-G#$`ybfp#t;KP00i~pN0!TAY12M? zh}k?T6ta2Kj*h=L84#MWt+4NsboTD`@gWZfRbna?_+O1Y=eO5?`nY=HSgOuL`5lkV zL>}MDP^_H@9u_)npJ5j@^1S36Uuy?Q=3c*glLf(BtAO%uyIRIxMw^f$?IQULV{0Rt z4+c-2R+pRF`g3B9ms7nUrAoDn*UzZ4R7rS%FyK~7g%C2hI(4XZD8kc-FYq-*t)A7i zxQOxw%5DDO^3V^S|D7r21r(BO5KBw-dZD#zR^;BxRN5#FlxGglPH>xaaXcb3+xA_irc2%O+mK zs|`Bwy%UQx+G6;x&BKh{ec)$b+Mqt-s80&)&WInsq;vJsz7rq60bA~J_VBAMkP*}l zZ+;Zh{LJS3rBbHGc~1Nyuxpc4uvA~WPR`VVA~0}kh)SAyr>bbsDeb<9k7O|JKOtq0MD6%0`5E9NAyw3h^x z&CK^az+|sIzCEEh$(XQvd8k#968GV1B^c`;T~!#K$sgWcl?)d|BPV?V|JwduoU0eE;z z6YPL6oAf;jzZ_3YqR)WRqgK%C`7(75y444 zybh@K$W;vBvXt+Rv`ZO49uIre*J>P(C!6YTAJ6caRNV_~#SluTt$C#RrI&T}^%5Ju z`4Rt{Y9;+1J;^UKz2BQUFEXy;eC-i{f#jlkl{lrJV{`60dBFm4^^vIsQOPhJ^=X$dT}CQvUpW8n_ry$P|3$;|T4Ie~A*@Pw?%LK( z`*t@6m~m`6xOFdB+Xft5{B(w#;Wui|5;%Uu;1C((wPQ;(J@WBMee@34ao7|nqHTTl zx;3YVKk&PcL51>OZdtQ=8W&mWVmV#Aqv@ON00P)4$Bg0DN{Y9V?zUTzkInmVF)!mx zGNzX-lzORBHb2*yxz9IU63bVQEa4G}|4^^>MmNJE3Jb-qL(2u%*E}wuqKz9AKp@Hw z*A2y{hrURxdvI~Ge)<|a+otE+_wml7${>pGfVgR0G}%MI5YRe^8>QV%HMU| zPFh1hO{*213qL%YNko4UBtis~C|11Rm{Z9mReeT?01JB4|DbK9(T@#!P z-ngIUXE!TZ+}yNP?y~-t^#~|VZHCCp6C6?1oAq~S{B_~6l{|Q7UP!PS1u(nD`OW00 zPlw;D-fD2k?*ub+z-AD+FY;phrL9l*9eAg=2XC^AKiqD=_O@HvPs~Gog^o=^{9>th zXo;;Qs~~4u{&S8F%savOFJ~eu0sw)}Ipe2gsa{zWPZ68u!KU?^eP~C94IM6@=Skkr zb71H&n^uc1X+4IpM4CUIz1%P`o7DC(Jv7dzR<_K;+49Xm(iX(kXt&4@qX7Xdm3r1| zX3wAm zKg(8L|5TYrVPrx1VPrJCJwwT_5dL)GlG21~VS)^9?e&ApKp1^ee^o$)GK>_6D*spV zzzObEVe9RpC_dbF;y@@TV=H&Dk^vi(+O*uxaru0k@cy-0^8rOOdCDafGx-PnMh{K~ zMxk<01|%JZm*s7BoYxm$@me>6S3cLpgHltXPK0AGSgvLCES6nb8?xy|^u_b}aN`Cl zNK+xXO02bo=me-T0B+(e|Bj3V3j~@xvFum>ddcghfd3ga1rDLwe?YB(neBnH{S_dV zGuX-ZzeUe96_5RY3%1;NfH|h0*lR>~ARyz@2H2}vZ0~hizHD%?h-UBT(vp%}9F+=A ztv;+=1_-yk!v8&Rgl@23AF2<-oFpyvM*16}xC$u2;LRm-Lk4?)20A+Q2o8*BkM z7MspK3sxJoEx@z3;WN^VZT-2D@ei%IWBt3^Gc_MCM?%WRyd~cVN>WF#7u43;#?Y%t z?8={NY!dr-NbmB>dIK~ZyKR*9QOl6vpRH!>Q*>_IlRGt@(d_(dw6SkjXpMVh9BPdNASK*oKE=6XCNk1J=cA~#kHVB3fcEV zyjh~If4o%%K8GxNxznhxl$GGa_V#wBh{x#Ltmya-OZwHT>F585N$?Lw|I7$d z9T^!Bhk>K{UCzs$(1$QX_x8WojH{w$tZ2j01}j?E8&$&&lA3h~*f%=K5Nztaa-s8J zOT6eUFgr8?IMvPqB+cl?Ht5^E`L8#ArvRD{)^R^`c*Ssy7S+_mdva}!l)L(qG#HGU zuP3kH>s;1?5)3wQQ8g|vUn_GHxIFZc(`%@i=Hpcro^EDyNryW-CZ?kGLMCeQ+o69j zpu3*8GAy3}0k>78*VhJJdWI}+OoD&}2XF5x=oA=7TR@cDX7HhTr~OlWyAF4ep~qVO zKVPp5t_S(tG7)<%Yj2$~mMDyMf-d~}^<2jKUBYymM91FeR!XDm%{l^;LaHcHaA+Gp zIon^fKD?jD#{Gb-+V;qgoD<7g1OeYkR0K6}5)jQL$Ybv~1k+W}03(@%I+=Y2h(|0f zEp7cuvk$eTd1VRt}AiC}PfH5vH`-~sK$5a70y^HfZz)B@Zbt`B%RQAm; zZRh~+U?;4a68iqIWk^|k2urfF^g5rjk_Euu#eqNkG}Mo~X6w3eRJ0J1I*cRw;Th;R z|C!~hf7#mb+symvuF)JL53{GV{Fg;cJ8V{1L>0q%_WKGiuss-dt*w*V0$s58BqY^h zu`9;VUtjGE^dXUjsymRMMsC}W8D&V8s)Q`JbWRq9)X_Qb*3FEoDc@^^23gex^m0cTeZ9YsIS{qYs0S(V6wMbiPw2-;~tqkr@zs zrzw8f!_~FRT{~uo16-)FXZ&s6Rs<&kCWxni)px}9L)Cd8G`{a$zx5FD6h(6Eb|sN(reJ{rB|DQdg=$WZmiE3UfZkfcJlwEa8^gOM*7 z9E4gj^SHL&{&!WurWxFlUvM>!PkMIGF&}2&r0L-@6+uw706MSvA{>k-)W;yAaAIYs z0uI#4e_h{cS-(cMpd?bJ!ltO%NEH1bpc{})iXYBGSAM?;_1sM4SI+|sfA@S3FMEY* z5~$v)wmLRD=Q%b6f|%F)!jZ5(x1%;>Umkqm#`^qj?FNHG8FUn>)fx6!TT%A#E>LYz z(t&HMZ?x*ZU53tq9a+DZ>F;|Duj^QIqGAIjgh{HDTqA_kTg}%~G*;BsYF|&zvzy}4 zY=2R7qkczjcclmvo~*x$K2xq`nx%C#xV-wAbgPHo%z1hLa$eUL0o z459bV?w?f+LWqX2*cr)$cu%k~TLcck1i}x1>x7U=Sj4=ygSn<^5T$0&QB7p!yG+)K zc1k7AR&!wWqljw7-4!U4QPp50NNZn((h{7k0ZUuv1k*XPO(3v1Xeo`Do)HNAbty`n zOBeN{y#-hnu@o><=dCs#8f=s_qLjPZhORSQ>pmLj zt=^ioiph!xk=s~qEfmPRBbi|q%O@F|&P^Zj#)>OA6vlQfG;iVR3SR3l1-jQ2H+BT8 zywt_qIdJdPH%YPv`sme}G$Gj7E_1a{QwIIEUKLcf~I|4x_$58HS4hFd;9$ zW7DVB*DV>LrH$A68Xv8uV=nK#HTv#mTu^Gjhz+311H;BIuwex*wADqJcG|4;CZYZe z?CCx%Ykregvhn--0j&DAt9#={x?ZD*O>(_eou(c8!C{!I>n6eMmD2oMcv0wkfHO7rX{*$6 zz8(!-NWlh8ZP}*2_w@nn?OldB?b?nz+?i9$gSJ@*GxE2&RtCie?8S>~Dgf10kWr#a zU%$baIfkjTjrQ3Yr~KoSdKDs{(?WB$gXo>Ujo;V18kC9`+;0hfk84<@duF+R^#?B@dcMCMky<%#03uB6qcsrb8K<60&z znbTTv*iD}30r~Y7JH*QP+Z%zg5B)H8`%&!MmV|yxP$}fZ4CDJd4L^w>Jom+=N^kLAo~y$4>>R6>=be1(M09?YF88e{ zAuVbin8y-u^(ImBb;BX|_Bvw^_l}ihx&E|VXC*SV$SKo5PrQhr+Yk&5m1Ma46#Nff zHLaV2K)tJ#7e4NPZEL#=b+r{PP5X3IaQZpC`iZS2@0QyURTHuxQB@G=bSUdZ(4$AG z;H3_`JGAlkg%ytghhlATrr+z!S;+I3B|5y4bC2mX#R!Efil$2og_Ow`OgI7t*Q4WC z^riQkiYpF?n#A&DoT$3xGnqa!8d{w;Xw;5atc7;`t72#Rvu!ig(KXBT58LGBpZyZ3)ky6Qw3y*;V;gfuN@{NWP$ zPAF5IrTpWGr_qhV%!>VPo1PVWME*cDeak81auJ;H@R7^?!P+I+SYFdaL8`G{z$@oG zQ))}yv+_c(4H$d8pE06KcG3wuZg|iz^|Na}wFz>PifZ+Y9!zx&Qa+@t(6jzxlEvoO$Y}%0{_2z{E)33siJ%nn%>3Vk+zz3)z9e9q3 zGJUoMJcZ`@4!`*z4_o95t$PtLE(8&Kz7;G~Rrulx#zheLE~@nQmoIk0nrYP)-4^@M zYo)=yog`$C9Jv+8xaEN8+%prAaB3I*$QZ@L zEsvJ!)5T(z8c})HPQgjx!i=6Jq-3Sl^A_ofuNnMbP~MGY6m#3|i_`dEN)}DAQ^AU@ zBH5}|&80xa53xV_;smiX>()14gV{meTyrr3lGD-V1($B`lg zHS)^%5d>pVw~{)8PWDsjQ+38R%?&n^9Y<+6)sBT8DrwTAi;Q((XK{e_QQpSlx7=?z4*;pTn-Sh-L=P*Og?&#Y^eMTF>s`L2&=XY9kR3*sGL^Hi0x&`qn4ngCd*< z%+H2%)YaMBEMB6OoE;qOah25Er6f_zy+o@O3+GnfrVz^$>r47+kM8ZUSk0@^W`3~+ zgxH^UpCeo)x2YaFWiM`FsnrL*Q9rZ!nAx%9E^IlisaQW!0B$Kjm3AC@}8+V8(sVy=Vf z(R_*0^Bh>MM~0t=Ws-EI%=HC#fvx>UCE! z&-Wi48Ht?%Q!NvP#V0!l9&WQXXJ;o{%A=A7?+p&N61aEqJrkW;hU07;thtoGU-0OX zCu^lW6+Y6w=SK}!Rrkl}21IJ`>^wXBt)Dfqk);txmg?EFk}`6v0y`gE?Z)>-M4eLD zCey-8pS`;J3f|C#61sN0Et{&O5%t9BXv9w5zDW{L7N*p~*XlP>#)E^tAjf(Qa}Yeq z$wL`w#!Xji1GO7SKR+oLGGFs8l~NB{Q);Avru?w!NBK73OPKvYNA#mGyyo{Z0V+ym zHI#bTsA@NqrgHVtgKrS^$N^7F>#9$ZhV+?-S!(Cx==PrjZn^GlQzp=v{ArZPYt@5Z zi{6W)cu-Mq(pe3wWI7x8?vp14)UjimBg)eJD1+(AO+jiveT)?>fS|$t?&8CF^pII#gbd(DYxp=>L&(MrxfNc(_S4i;&o>0-!fzbB~iQHLpOMhc;xVfcyhzV z>rw|{p#)=(p65rlxJ3LAnM%bv)Lgj8C+3o5c@G|V>yqu-ViK`d+ggvQAccPm77y22 zUd+nj<&0(L6PG9IT370&dg?P@VUAhIPT}3F+(K}1wCEVhz>xDm61E<(UnqylycH=b z_sKo*vsAvbRqgyWVh#sH~4)vTpNsnwQPJXeT5-Nu=_21D>UeOOmN1EEPL@A7_k4)lUzOw<&mR=Mm>*XPbkjhNTv{+sx z-^vbir%@N@w1zgZ7UxO|LqJ6mduPtmjec`_wcD$~pRxtktcYLV@W7bIG&gJVv}>Dj zzUMl1Lg-HR_EniclPtLvam~Ye;Qh-bKkkl+W`EAcq{=k2O_(^`IY)yp$)vPN;bG?%VD!X>H4jF=+fr`4-^#ZQJy4M(F; zk#YuakZ6wvO-4Q^529*Q|K`&((W_QYeY1s}LO#|rSnRy zS-fuA{X}12P6o==%)s0?onW$uvP*eM9e!(4GN-q|%4Nd6Czl4nn`G4QwGSV=$g>V*X5L_x z$sEh|QIhqIPj(r5Orb3fOLhvKHI3MrqqEd^-=kKC5-{7%T(Ks4`6Hs1h3BhJCnh^E z2aE?zJ^sW7=j|D8yF$KBR9kF6>0O(_1GoJ1Sf?-C*@rvkh)WMKOf}Fc1=Mlr8gn6} z{lKg8DrUMVqdWxbJ&6Z6hbZ@L_{6l88dwB@xa!<8TgI&w!ek}a@IdxkZ@gavFIP{c zxh=zER5lf!%IdCY_gWeomR%e53+^Ke`;wCf=t)0X8ZVux)0GL=30$qr!VstDNpX6r z3imURq>tI~7ZhP%!n}F|Va`cK{*aqr3{5#=&c(JzBQSH4r@LV-8^w`leaDv0s-{u( zN3R%*sLupub*&_!Yo8?7w*XZnB-4W}uwRn>f^bW+Sl}~bH3#&XQtEIlc9Du{mF+V7 zSp}^yS&J1?5V(pTPoPb)f<^;>NVoZ%#^xG}9Darx?`5(5B}cKFV0H=54?*T@Z_ZZ3 z!Ie!BLU*$+9f*Oge$tk4d+-+{)kNo9c&b^S&ii&6E+7DB&5_~fLLJprv>>pnO+R%bhk&ROi%LLX84QMWZ?x#4n&zGTZUEj1C4?ktWDbR{d`QF%ofe>qIQ9pHcBF!l~!`Z=AnY$pE9iGDN; z$(ktwHOqthq>k2K#UuSh;tB>kvl~Ml`c%6WzZ^y|_qm~?>gN5_)6_njYM=7TtU(w? zpt|DF-AeMab+%FdddYOvVPpX+%QxbFADvo1qVKMyqPkQX^FxQFc8XeufNutAUK`nZ zm6F3fmHT=7Ia7k`J6mqd)>oCzFHi-_#0O1p7YRhqCYajr)-<8mRfY3HhD)U^8k;0F zs0v^>nGLie6yXiLv?W=jgSmhCI>w{6M#w!74Tq~gIfS!M5sLY7Do4ot_1UW{b8rV}fwUgdV81#t?XA)N)40p^#bQ-0ImuUcn&jMV@r~`T?0JRK?rqZ_ zGtha4iPTlEsyG$%I&&8SBQ?XuQO!yEi&~5Zw?Wn?% z*o=*<45l@t6Q8{i)199j{D~$&)Dpt0d zQ$YyMq>5-Bw>q0+%B-J!#w{x;E0$HlY`k5WD#a!t2ZOz|o|dLrVV4^%t{guBpii+4 zJPgJZzDPgvGb@RwS6HO`dQcIkq`Kzz61f7n&8rySLsg1_`by-1Mxn=Y7>^X>M_;Gu zLK*ekyPC*hVR$aJx0Xw7^?UJKEkc;oQ|>)QQWQPrp;O!Up0cgh40O9RrYt%d`#9Y< zFVmrhoP&I8ae@&HHt-Z!s!7&=Zjy+v%C`oFVd2visXh(%0EOcC?U`#W z&3mj@z0KW5+;f=69q&On!9}UZjma(TK6rZe2%nOG;x(M=v{If=NNf7IxhcWKwjyF6 zo1Wxr8BvO^c>2tBE{rz96X*RoGeQZ$b%%L#8gbJgt42XYoiscYOq^LLD8s5sbV%?N z9Wp9dIo)8bed-W}9wk3|KF}tfeeOpHP8uI^WxqwuB0V)wW(u(v;N<-qSj*5gQCRFP zPT7i5zVeW7PY#dPx|-UU?&oh6epwT)hmdi-lA$wK@Fp|0rbxm>>PG(S(lTLX@l@kG z1}DBqJKs#uNQ=vldz_Yr&MwYi116A zIYm!G7X{Ac>Hh&9)7|p9dyZZ(SSz0Ve%bAhsE?S|pn>Zn(w!8O2Tusn!cR@dAB1Di zo;g+-m%Vu=>tjFne(gw~(Z{D6nh0_NS<8_Mnalj0E>)}U2OBgDVpA<&oQIFah?+^s z>Aj3ndK1<8aj~Iuz*}~KEXAxPY`zlsN+4;dN2(h>%51OKj*LM#Fa42NXX9JgeUUeg zs2`EmCnss)D?dl~ETq!?1-yg2G6o%DKg78xpgVnJkwY3T2U~93B0OtD4zB5X-vEA& zV;g>suc5b{4nGvt{Nss*`0*B_dW^0QEz`fsy5@>TtMJKc&V%Y#w0n`RY8a22uh(Kv zKSdf1CXt}%5pnpNZN?TeWw<2Gzck)Go4c-~5#$Q{j_gueFa9zP3>&aAxyZCeYe=HO6Le%jCZk4K$q-*srcjr4uNEqHMd-So@=-9CSg z%MQV&!vq2} z47q@Q^26ju?~l7`d!%?uLvO-7IN@1#F-|u^XJR?LtVhf$cJtHln<70XvreJri59>iC!vHj%{2!!vs-OfTWsSU z=9arp+%e*Ai`73cL(Bks!}{SUm|Z2 zppf$}?_%VRd(KHY+kR;}iziEVIuNH$S=3Zrt7-9HOl{JRhaf!F)9?#*F`~rfw&#<5 zRGPcZX4v_kIBW>q-PP6!AFf9I(`N9H5oQlNye#jp3sGfAR>SPWGbzm{qaEh1tS$nW zCPjt&aF_jw@IaE%mEh+G9NV$s9(N4C;5pAsu4R2FSqh7YJ}7b26uC{Bc(C=!r8nG^c!7}i=dzL z;bQ%KU~AuLyIrv6o4LOw8ao$nZf|&Ftd5kKc1liYC0AH`g1Qvzwa8TT*0#KHQ$r`G zuq=xN_F}=dd~qLR+=Qegs)$`KdVSev$axalG9HO}j9MxA#%j)61eV+WpS`wA4A+>h ztv4ozqC`uph_SGERepRl97{Mu8dE%I6h1dz8UBdkMNlndnI-|_cxbp}30QR4P^PcA z$ao;HDPQbDriCjKApyLzM)Hm|&!xUpw6=bC?s9n}Uj&ljeE*=>0xSBcGB|TTPr|?N zJ!iOta9(n77dEBwRn)-&1cr#awHI$7VliBF|GUksu7;<6*=JK5e+RM5bZQ0^!fVb^ zqsA2&^SLppe>~3R&o-ypodNbLHE*@-mE87T$qd_B*he3TyqH6Eu{64IDkQCthO>P` z7Xp2B*>GDlt6r~EcYGB-av>%sRtS9~#m7aX>2o&9H|DU-{hMS`J)zWhdwOb+QJhrl zec3X*%Yk36Wo&aQTU`)jd)85q_zpqVXThl8?x9PEr5v}vL`pWuH}<`k)$B04(RVBV z?e&IHT4S;Z>4Ie>T&>-g+Pl|Gp-dofu3{KVj@2-);k@2y6XBi=-u|I?Zns^* zQP-Aon!Rdn^Y4R&E+;*NrR+PI82+H-wUm6i$XdN+%RU?hF>~GaNaQAD++TCK7H^NW zevGCYF^VLfeu|Q)B^vwULMZjlf21EL-;?MIm%gRFim2EvQXWK0LBx;GC6`WOT5gNnO-ZHUu&C!VbmUz?65zk_ zYa!)wobzVPv7lJ3+3rJ{Ry?T+!n09_{3+RE2Q_aOJ<+Y4Pu2fyohPhW-Eu(yV8kU9 zWsu~tiR|Gtf|yEi>NugP7&u$-25B6WEBqx#1#U|m{a87@J>iOcW8_Sy*`J;I4VkLu z9y;}13)b=ZG3Jlv0jqu(j-F7yjaR2d4EeLp|-S-715TxphQ+dsF+0lh3|E@q&Du~!z3N5-?l2Pue(o{bkJaWlc_aq_qS2I_lBcXBDND7p_SN7{XT~gfdfjX50@UF!hx^ z#et`7ln*F%)1!`jAlwm0N2#BE#zCS6s_=GJIy1kN!EuS85SL4}#l5CT1rJLlQGw5y zd~hWG5HDdSuw8MugkHr!#j!;WWfVmqWvH?kiG1oFjJFwm%s|NiiM|4+fKfzZzODDCZ4|fSPbTKfQxXd#j#v5j1fgzcIJ$mcEwW-CL?xN ztgFHPeTTYj;_P1w**T~HkhHnC>O>9ZPfY>y_{MljHO2hiqmFD^En+xn$jE5{vyeQ9 z6uM)t5>dU)?`iA=&f7^X;tnMB^l|(kho&N?qKHI&(TJK4Ow=>P7CPl?v4zd2fYX;k z$g(=Q{Ips~nb=gO6_vIt@MA)WA;!TXM5c=d&!7Lms~ zDN_qUlL@Ad;A4KEN_C`(Dz1ea}H}lK2 zpJP8QbS7Vvs82wpCyB*+zeUOCN+w|rwpT(h*Z}%)6Ll~>oFIOr<_x7q?Z(f-jK9w0 z-E-dzyZh61olp}h8#9r+bq;Tzn0i}Uh*MP4T_am>#E*!m8gxLU{2@;+(sYnrIEAKO zzwHt?8vFIL^^} zY1wB|)+bH#Sf{k;Sgel|+9lRvzzDCXN1-dKo5UK;GMv-E%KTW;@^a0cgi6*AL|~AY zZm!$RqgB+QYb&@xlpOiBzt`EC@Bjs0O$$DmUHU!Ygwx`&NF>Gv@+K7LUmt`JriSg_ z%J?NUw|2!vDs2S266XRDK9ZkDK621L0k>P8dLKFH;3_nJ!YAnEbDu6g+s%M?(?NO{ zget0NJtEdcdUph^vntlY>#Xc~RBitNwz`HTJDPUhG?+N*s_G#f?I4ty=$50m*sjA0 zuj)VV#^Op%4=dcH^JimjxvFk>k)uSJG zlsr4Uu`0C(<7|v~qa;2WpyeG;WLDQ@{3%Q+X;VU^O**e#rHN9?s8aCKq~ZpF*NjnP z5ts$i%rG#s-}}yVK*9b(ZOy>$f${k9IMw{NH?(*9C=Dhmc_en?nUKhFa>0tc!Zp0q zQ_2C??u9b8N57^wNG;8L5PlQ4Sp{Rj0Enyg-q`sXVv=n?1xuNb*#uzQja59%j88N3 zwo{~*;q^3e86nIb&Gy1=f|Z%R)+Iul(iOb(=pJql`?FZXS%|MxS@YtaOuXrh6P*)& zK8FfZzsu=yYa-L`$FnpH^>l7I?|R=A=O%%(p&cjpsO~P2X}fK6OOGbTX}{c>Qe7pf zDURWlow=*wrpLH<8=;BBNLhqEe*QxzqfWeD#yqz~bbFsf$Crd)*Ij!~)!m+Ry{5T{ zD|vWEon2a4GUu0pah+Z*Bk9R=asrh&|5Mr|X(7_W)pxXbM136iiukQ$1}EXE5(Bxl<$;1i$5}efk0RzzrI%%J)jTIUK*PbTpjv3}?3O#9#oV7NSwbxyqT!xSGZRoTi5|&&Ih>pVr2a9j- z^1IBa>253V3R<+m(`yS6w#8TKr-n7xbo_eL8>zK*R}`?g#wdS<{p8X>3fH75B}WZd za%+CD7y^gOiEt_Z8=XC42`@t&L+%WIE|d{g0aZMjFsCWn(&{oG&Gj4ili>#t;gU7^ zmt%KL9qepZj17vJh^7=i(VN|^ykt+TYO22DTB%M5L(wE>JI_!$ywu4&N;2lir4kQ> z%RJ)*Gg*#e@_x*{eQmO_%Ui|IxmT0+Mu%bHG{d%n_kUVWxumhYiuIg761WESiNmz% zf%v$(5-&6zzjlzCf&}>YqmL?mZY@03DldtucU|>~Jn}kY(8(u_`Pp_D`%#6|BJZLd zP&QUG?2c5co_B?c(>&_TiT=|1>a90Jo;06r7L20Xr=afNUCX%ty*?9f5IyrrHWi^6 z(rxKjhU-^RCEPj`^K-e8nr?s(9*>ewtiV%BCGiy9bm^;2iCa-c+LK0qz6GwbC^J zFW6y0N|gx&o3^kEX6FZyWgV2<>n0P2m)LAu278SI9Ujj9<{@B7`|CC$DNzFrdur?#70sd6Ac*DnX zc>Y8RM#QaqQ8T?T_E`LK9&5#NK*14Fq8On!QKQ*q=6jT|T!X0pvP^mNqZ7i4nRUWp zB}LV;tVV5H(kiCdMZrWNc zsv=h54R~?WQXq=O>PGDF|6HkUczn&JoPt?6C z4jE0DH**XApxZO}sIaN$mPnhE@rwLXA0oM9fy`w46Ixw^%7BnXHfW*ETl+Wjk#8Bh zX~wqO2t5-rzx9T5e*=Mod@soF3`Ufr#kWUNUIXHmv;wZp-rA;T@Y0Upk6D9tSelXm zIt@>ZGW&U=2Bu!@^2bx3&Wik2fi!|U(>-gyQHRISb3$VetwHjQ$qv#>HXDEh5x)o? zu)t$i3?YJ(7vMcgrr(@N*2CCISoKubI9Fc0O|Xa zomzxJZ|r=2t+7H?z5|w4Jj6|#WP%JJb3}yZ!<6tjvMoDcWlA2cz@&?)E`+PA$*i*= zVX$)&c!~VVQf^WcVB|SsWd%k|Z(LCZ7#@t4v;hIY$~j^W{2YQucL$ehdijlbUW2Hw zbAF=8MZjX{j-4(P$-JKpO+j#!qqvuJlz&1{7fT5XF}=2rzXP->BY!~Jg7_olioaIj z%>r)$4D5*Uf+G0*!Q64=^w!KK$ECCzYPY!BueS!=57ad#RT4^Qa;@zV7EqEb1;BsI zj&9)Nupuw7bWQ@%W(b!7abIDX7n2L!9>G_F zblklg8O|ZH-Q(6C@W+tguRfJef{n1~9O_3AYMpot-ueOycHj&%y^ReQ`1tqHeEIjo z`}-^Kq@HdFjsFZFQ&y3pM*&y`c1E%giFEx4C6pULAHMDbwT=8b0J>;@iFVdJXr=^2m0mxVMAvD}u%i$q8`QiM1?h1S z!$aqT)Nj{ujswe<0M14sE^8;|zWIFzq+ZoLD=f`2!;`xk{_ z|4meOlciR5(t)a;W0zA3`8*mc*3T;X#T);1VY%13=12y8+Z89S9D7MBi#6xuqy`F> z7HphewLaosXTwb9K*5ePpgfg#9U#v;MHkcuEIa%EW>1$Z{ujM%e&*)xo@mROHC<=j z8^vEb14!;?fJ;KsiMh^`E$-O>w0|`}#3A~p7YO--uzgs0+J=|&_pPDdq2c-)wB~>Q zGI{r}>G@AzhGPD2IPtvKvOJJO;1md4pfYQtZJ`lx#CbwS2X_8#Bz66%^Pl}MQic8p z`?uC${fu8fn(hCM+4#?i{}IpMI`I2l^7j|u!+*r{w>17Ep5LPQk5c@W#NX?$zrO$< z{v)2hrSYFR^IH`EQHtM^_T3hFJ|8+7 zwA8)1`3J$PQ(~K$o@(?aSOS*vW5NHAuXn#IY&2nJ`oC}B*G)nd*4qJq-rm{~uj`v& z$qzSTbbogO`fYdO-)wsR%ZdMPcl3YXiN6A94MD7}bsY$Q>jd$xoi_DBD_-kc+OiN9 zd40bS`HxL6Wh3}8R9#g5*2w+wD2Ib`a&jG@ta1lPuiXKXx353pb6wEhlqr$LB`+@z zfd#O;=b(*RGfJk4A6727xN>rh%$M6pQ`7RNdJW5DF*HQ8*!M(1J-~E?02Is$Fy*)V z{(YP^&4By3NBvBm3i^)lY?qh($X)eK0LTfVwY%O@Q?l(KqAF_T;U9_Y#&|*YDh^wB z2Y?~tmte3iD6lou=LI%L^zYbbD9*Axx=Wk`HWxOc&xdX_GZB^#31XZ?6Xbw<+sSGN zEYyD^GFj9t_F=ofYQVjwsmPKm#vo;;sod{T-Yp)yeG)`&JxiGc+wWNH@fhs!-vQX? zyCQdOf}Q&aMAQ5&#`Are2g;wO;7WK_aHHn$2=EX0j(`|PKAFx9_SbUhvs+=!`=Cwh|ARp6Q1y3RUa;oi_C3{_?G4p+IKKO@-Kn5{{WjRw zb288!0QUu;V@c%F26x&j6s=hDtf1N^Xraa2AOY0!>wZ=^u^w1$7LsQRBI1e3=6hj7 zT>mX1n-o?F7g-xrEJd#|=%dM69COX@x0C7;vb#@EV}Ck2@Ui0 zMIdjbv&nj7yQ(0hgUzW>yl^O@f+*98_>t!#(^*0;7KSyC7RXcA=2piXJXlSJYs+Zy zhO=(@l-p1ZcL*{CI8KV^aTx3=6sv0YUt_fAcKwp_j*96i0#RWFpC)CqnkF{cpJgQ) zI0>RtHR{;A+SWt=voyWn+hNT&cn@!e+5NR1+?$YnW?iw%pKvrlwn+DOv+qP! z3408;WNO=Jg<>QHX2FuuRM$SJw>invrz!wOQD=D87NyMWI$6O5WCclp=hiA<=K>t% zcOrqk(7t=4`C`l$H5U+_IQC8!8+peUI*G?a`GhywxJa~zOj zN8a3Mrrz*ZK7#E~GbVFj59~mg5RNgHsY(ZmX_t|4-lSvCV1n0thM^6stv|@5{@=uK zt5O>Q@pBvCMn~>~#y=zqY2BRs70@=Yove+CExpn7(SGbPD4aX%Vj*>P+PRJrmz(~x zJD>2xuQRh9(HX)TH$?s9$PJoS7xYr!4lDQg)#h2K&EhS;+H6{H6DPecQ`LYkHKYI| zN}*N5rimd}W*M7a=@jgU{zz|geJ#=4=c9!E@>3~pdG-Evfbnb|HsjbyL- z6|stcaG~ES2Bx1!(zC8W@%8^uF9M*j_^X0!#>Ky#(mo%xZLUFAs zw!V6LzWVXatI5@`b??mWI(M=~|AgYh44F%d2 z{=!4{v!i_|sqjT&@u0>LFy--HXd%$ZsK8&Pg!lQn(ZwBe-ZutSpd_Xeo6HFHUg4Olu~ zb8bU3Dw3u|0nfjo_+jB{N7X*o6im3e9BVW4`N5E7 z*`kEWwQe@SCxkW*dZDp8XUm+SH-@FhlY_^x4Yus*TmqZ%VDMfD6FqBUd+pStpHJ;C zWIaH@nl(Q`mhAw=Pc4@Px-iX}zNR+2hO=e55L|4TxcN3Un^FDKzrxM8Z-Qo`rb%K| zB|pq+&Yd-DdyhRvF7rh%_FS(o3i+n(m%h07NA2j3)c$6a+DhF1fa6>0H3 z?v9!BNSo@|8ybOSFSU{CL)MnZ1@-BJwu3(GK{gH7pA(t2l9Hu>#5DT*ssVRjQPv>B zv|Xtg!b2a?)0Ej|jf)+-MvVtBor5S^jd8$A-KdD14j0T!x8alCQHKUFb?~oPy3C`n za^e~V&8jV;N7^!SZD)g5#|6t;Pfjuo9~MI9p&7#s!HU9jOC4T-BWFg>l|&RM6+2}i zXkSUY9~Os-t|&ZOk858->V10g^HZ2=_0A)e62t5K>PIXt3@l79gz*K0F{TC&XQ%}F ziY#$9w|vtJ8S-H>WkTvwF9ccbmxky){SBJi54QIDJ=q%GF#cTWDsj`|Y6vKT(NK$8 zE+KFahb+ddM&{D%un6~qust9X1#<+_gPFYbaoknrZlpx7O-Gw-G7erz3h`g|;VJX) zcGp{#*Oz_=g`NnU12q2MoaCwLI z1Suzj%2`}_9cko(@nKSs-_ctxiX>rIdV}6cplG zVv;Dv@_QD925V)LIBCX%aj=Z2Dx+NTk9H=$l3OnIYbx3T`)Yq1%@hSQrrF>+sH79N zIwrX`X41N}V3HOxyx0q(E80q-#~+=k(z4D?qwH_CPugxk>+E?f1UtK(W$ae9(@of1 zykEDqy=n>MESP(j6S1m#hXe|B$w64O&s8FnXn^5NaS13Xy_^jvt5Q zK35JV#@S8RT1|9j%D8KF??!KxN!j(VQin2;wYw7Ns+i=EF#39V>{k61Fqs3s*G+gk z>rZ(q%~x&-jf=+|s3~+aiP3@8DpxHrPf35y9yRCwNC6HhH7eCV46~$$WoYNLBUduN zx~Rt{?L;MFc+CH(MVM+SuDAyK0Svw@7!YRYB}hOQ+Iejls13}!`nTueO$KC`nhO#h z#L4cHd7$z1VL|mGeXB9XuB+IP4szv}9TeXV*odi-F;1Ssy7t-XEcbA^d>l!YUiXJ z2ntFGz1WImm05@-CA1*s#`%Xt{Q+Ue_&!)n|Cx)3-`t2Gffl`hg4?k)_p1 z7c+Qasm4pKH!dW&CLu=eebFK5Xw6z$_+q|*gzKuwCcW*XD#NcMUq888J~C?S_5W=e zj>25=C!>|66=H5_JyO;C?YfJ|9dXXaLy%%POJD8nTJq+j9s`@N zW7Mmhsd%o~H2RymuVn_5gEffW&OpVppdS(oCM6rAjvr`9!W*1*;95O+ddHkyGGOUzruW-it9scju$6 zd)@((^x;~GQ)tcC?B^)mBd})Q+hDc5e&{Me@3zp47YW~-ecl$8p#qjw_MhTDV6VO1 z&T+HGb`!^Q>xm)eLDneczKLgBxi!zlrv8Z0JeiW*ySK7yZT{`}^L}K?khI)Pu6?;< zFQ1kRp|SsR>Q=)#uqQd2+!fa>4TapAJ}`z-I=l;)a8q2d?48leDF_wA_&t}M+zD$q zfvw9Ab-F&$bey{D;Md}Q-F7qScdu#Iu~WU_{6JLV6z=}ab3#;oZ#Q{27~Yk*y?{df zU+leiR8#5OE{xPcDgIrAI(1p(ilR zP=#nD1QOavi3CD4lt@Ct*}<7P?|J_^-#Tl3>pN?G&p!lG*xCEu_j8x)y6$xl6Q0tR zAZ6t-eyM#{tz)6Gy|VX0;4C1F_L^bgom(S&#Jw700m-#NvRxV$VV#}G zZHtf0kUQ57D^bXUATfjaYWHNnSg;_#gpa2AikjULH12ZtNT+3Sl?2!fW9D7YJkBu< zW;;UmO7#ji2X5!^$FhqS)~sQlVRrVV(J7OsUzWn!3-w}S^ZSj*k5VyGUy2vc7f0uo z%iYTJ81%bpCihgJsx3?0#SfLOPaR$y9WHjw<+#|k!0oaY?837@S!1Ztp%6hWX>D#2 z(3U9qiHAeJLeB1u$hC%KUYfjrE4s4^O^UsGLoS;W2zE{goHtP+%_&eU1EcN{B&d?H z%pIIcXiFW(xj>kiE_r#TM?~(S#aZ$8-I>rLbbEhPW+k{r(Al0b=0e!a_bmxD$A%$0N@TA-<&IXs#I*kmx;|$$Iy~C(8~}rvyq3e1 z0uh2LhdIc4b~qrznKzV{I3TDc{-ඪ%DNMNJX{XyKLN>KVu5pMr`7^^ySwLPn> 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

>m+_Clx&w(^Xy(|2YvmbHea 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 q4;YA`TJiZC$nB>*JolSJ}GBN!Mo5i1D^ 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

PMlsRtCI^3eOApnI@h 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%0ACu)M&gTl*oRR|=9gMR` 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 J4#h3@{{iEcPpSX_ diff --git a/docs/cryoet_data_portal_docsite_data.md b/docs/cryoet_data_portal_docsite_data.md index 0e1bb6809..50a1add83 100644 --- a/docs/cryoet_data_portal_docsite_data.md +++ b/docs/cryoet_data_portal_docsite_data.md @@ -24,16 +24,28 @@ As shown in the diagram above, the CryoET Data Portal has 3 levels in the data h - **Annotation** is a point or segmentation indicating the location of a macromolecular complex in the tomogram. On a run overview page, you may choose to download individual annotations. +All data is added to the Portal through Depositions, which is described below, and a subset of depositions are displayed in the depositions tab on the Portal. + For more detailed explanations refer to the sections below. -1. [Datasets](#datasets) -2. [Runs](#runs) -3. [Annotations](#annotations) -4. [Depositions](#depositions) +1. [Depositions](#depositions) +2. [Datasets](#datasets) +3. [Runs](#runs) +4. [Annotations](#annotations) + +## Depositions + +```{figure} ./figures/depositions.png +:alt: Depositions defined +:align: center + +Types of depositions +``` +Depositions are collections of data submitted together. All data being submitted together will be tagged with the same deposition ID, starting with CZCDP (e.g. CZCDP-12345; note that only the numeric part is supported in the API). On the Portal, we will surface depositions that contain annotations submitted together. In the future, depositions surfaced on the Portal may include tomograms added to existing datasets or sets of datasets contributed together. ## Datasets -Datasets are contributed sets of image files associated with imaging one sample type with the same sample preparation methods. Datasets contain runs, where each run corresponds to imaging one physical location in the prepared samples. +Datasets are contributed sets of image files associated with imaging one sample type with the same sample preparation methods. Datasets contain runs, where each run corresponds to imaging one physical location in the prepared samples. Dataset IDs start with DS (e.g. DS-10000; note that only the numeric part is supported in the API). The Browse Datasets page shows a table of all datasets on the Portal. These datasets are not currently ordered. Instead, the left side filter panel provides options for filtering the table according to files included in the datasets, such as ground truth annotation files; the author or ID of the dataset; organism in the sample; hardware; metadata for the tilt series or reconstructed tomograms. In addition, the search bar filters based on keywords or phrases contained in the dataset titles. The dataset entries in the table have descriptive names, such as "S. pombe cryo-FIB lamellae acquired with defocus-only," which aim to summarize the experiment as well as a Dataset ID assigned by the Portal, the organism name, number of runs in the dataset, and list of annotated objects, such as membrane. Datasets on the Portal may be found in other image databases. On the Browse Datasets page, the datasets table shows the EMPIAR ID for datasets that are also found on the Electron Microscopy Public Image Archive. @@ -105,7 +117,7 @@ The metadata schema of any JSON file stored with the data on the data portal's S ## Runs -A tomography run is a collection of all data and annotations related to one physical location in a sample and is associated with a dataset that typically contains many other runs. On the Data Portal pages, runs are directly linked to their tomograms. However, in the [data schema](data-model) used in the Portal API, runs are connected to tomograms through the `TomogramVoxelSpacing` class which specifies the sampling or voxel size of the tomogram. For a single run, multiple tomograms of different spacings can be available. +A tomography run is a collection of all data and annotations related to one physical location in a sample and is associated with a dataset that typically contains many other runs. On the Data Portal pages, runs are directly linked to their tomograms. For a single run, multiple tomograms of different spacings can be available. Run IDs start with RN (e.g. RN-427; note that only the numeric part is supported in the API). An overview of all runs in a dataset is presented in the Dataset Overview page. Each run has its own Run Overview Page, where the View All Info panel contains metadata for the run. These metadata are defined in the tables below including their mapping to attributes in the Portal API: @@ -180,7 +192,7 @@ Runs are downloaded as folders named the author-chosen run name. As shown in the ## Annotations -Annotations are summarized in a table on Run Overview pages. Each annotation has an Annotation ID, which is assigned by the Portal and is subject to change in the rare case where the annotation data needs to be re-ingested in the Portal. Each annotation labels exactly one type of object, such as ribosome or membrane, indicated by the Object Type column of the table. For every object, there is one type of annotation per entry in the table indicated in the Object Shape Type column. The options are Segmentation for semantic segmentation masks, Instance Segmentation for segmentation masks where each individual object is labeled with its own color, Point for point annotations, and Oriented Point for point annotations that have an associated rotation matrix. The method used for generating the annotation is displayed for each annotation with manual meaning the annotations were created by hand, automated meaning automated tools or algorithms without supervision were used, and hybrid meaning the annotations were generated using a combination of automated and manual methods. +Annotations are summarized in a table on Run Overview pages. Each annotation has an Annotation ID, which is assigned by the Portal and is subject to change in the rare case where the annotation data needs to be re-ingested in the Portal. Annotation IDs start with AN (e.g. AN-2480; note that only the numeric part is supported in the API). Each annotation labels exactly one type of object, such as ribosome or membrane, indicated by the Object Type column of the table. For every object, there is one type of annotation per entry in the table indicated in the Object Shape Type column. The options are Segmentation for semantic segmentation masks, Instance Segmentation for segmentation masks where each individual object is labeled with its own color, Point for point annotations, and Oriented Point for point annotations that have an associated rotation matrix. The method used for generating the annotation is displayed for each annotation with manual meaning the annotations were created by hand, automated meaning automated tools or algorithms without supervision were used, and hybrid meaning the annotations were generated using a combination of automated and manual methods. Annotations also have an optional precision field, which is the percentage of true positives among the total number of positive predictions where a value of 100% means everything found is actually the object of interest, and a recall field, which is the percentage of true positives among the actual number of objects where a value of 100% meaning all objects of interest were found. The Precision and Recall fields can only be calculated by comparing with a ground truth annotation, so for many annotations on the Portal, this field is marked NA for not available. @@ -232,13 +244,3 @@ Individual entries in the annotations table can be downloaded using the `Downloa Instance Segmentations, Oriented Points, and Points all can be downloaded directly in the browser as Newline Delimited JSON (ndJSON) files, where each line in the file is its own JSON. The download dialog also has instructions for downloading using curl, [Amazon Web Services Command Line Interface](cryoet_data_portal_docsite_aws) or the [Portal API](python-api). In all cases, the JSON entries have a `type` field with instancePoint, orientedPoint, and point for Instance Segmentations, Oriented Points, and Points, respectively, and a `location` field with the x, y, z coordinates. For Instance Segmentations, there is also an `instance_id` to group points into geometric segmentation masks. For Oriented Points, there is also an `xyz_rotation_matrix` field with a 3x3 rotation matrix corresponding to each point. Semantic segmentation masks can downloaded using [Amazon Web Services Command Line Interface](cryoet_data_portal_docsite_aws) or the [Portal API](python-api) as MRC files or OME-Zarr directories. When downloading all annotations on a Run Overview page, both the MRC file and the OME-Zarr directory will be downloaded for each segmentation mask. - -## Depositions - -```{figure} ./figures/depositions.png -:alt: Depositions defined -:align: center - -Types of depositions -``` -Depositions are collections of data submitted together. All data being submitted together will be tagged with the same deposition ID. On the Portal, we will surface depositions that contain annotations submitted together. In the future, depositions surfaced on the Portal may include tomograms added to existing datasets or sets of datasets contributed together. diff --git a/docs/figures/depositions.png b/docs/figures/depositions.png index 9143729273bf441103ec31d958f0a70add6cb8dc..3e3cc188873df4c4f42aa77a947f22880c45211f 100644 GIT binary patch literal 150362 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�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 M(Yld$-Rjx@0Ey1Wp8x;= literal 146099 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
!regex.test(location.pathname)) && - 'screen-716:hidden', )} > ) +} + +jest.unstable_mockModule('app/components/I18n', () => ({ I18n: MockI18n })) + +const remixMock = new RemixMock() + +function getTabs(count: number): TableLayoutTab[] { + return Array.from({ length: count }, (_, i) => ({ + title: `Test Tab ${i}`, + filteredCount: 50, + totalCount: 50, + countLabel: 'objects', + table:
Test Table {i}
, + })) +} + +describe('', () => { + beforeEach(() => { + remixMock.reset() + }) + + it('should render no tabs if there is only one tab', async () => { + const tabs = getTabs(1) + await renderTablePageLayout(tabs) + expect(screen.queryByRole('tablist')).not.toBeInTheDocument() + }) + + it('should render tabs if > 1 tabs', async () => { + const tabs = getTabs(2) + await renderTablePageLayout(tabs) + expect(screen.getByRole('tablist')).toBeVisible() + }) + + it('should render active tab', async () => { + const tabs = getTabs(2) + const activeTab = tabs[1] + remixMock.mockSearchParams( + new URLSearchParams([[QueryParams.TableTab, activeTab.title]]), + ) + + await renderTablePageLayout(tabs) + expect(screen.getByText(activeTab.title, { selector: 'p' })).toBeVisible() + }) + + it('should render no total results if total count is 0', async () => { + const tabs = getTabs(1) + tabs[0].totalCount = 0 + tabs[0].noTotalResults =
no total results
+ + await renderTablePageLayout(tabs) + expect(screen.getByText('no total results')).toBeVisible() + }) + + it('should render no filter results if filtered count is 0', async () => { + const tabs = getTabs(1) + tabs[0].filteredCount = 0 + tabs[0].noFilteredResults =

no filter results

+ + await renderTablePageLayout(tabs) + expect(screen.getByText('no filter results')).toBeVisible() + }) + + it('should render pagination if greater than max page amount', async () => { + const tabs = getTabs(1) + + await renderTablePageLayout(tabs) + expect(screen.getByTestId(TestIds.Pagination)).toBeVisible() + }) + + it('should not render pagination if less than max page amount', async () => { + const tabs = getTabs(1) + tabs[0].totalCount = 10 + tabs[0].filteredCount = 10 + + await renderTablePageLayout(tabs) + expect(screen.queryByTestId(TestIds.Pagination)).not.toBeInTheDocument() + }) + + it('should remove page param if greater than max pages', async () => { + const tabs = getTabs(1) + remixMock.mockSearchParams(new URLSearchParams([['page', '100']])) + + await renderTablePageLayout(tabs) + expect(remixMock.setParams).toHaveBeenCalled() + expect(remixMock.getLastSetParams()?.toString()).toEqual('') + }) + + it('should open next page on click', async () => { + const tabs = getTabs(1) + await renderTablePageLayout(tabs) + await userEvent.click( + screen + .getByTestId(TestIds.Pagination) + .querySelector('[data-order=last]')!, + ) + + expect(remixMock.getLastSetParams()?.toString()).toEqual('page=2') + }) + + it('should disable previous page button on first page', async () => { + const tabs = getTabs(1) + await renderTablePageLayout(tabs) + + expect( + screen + .queryByTestId(TestIds.Pagination) + ?.querySelector('[data-order=first]'), + ).toHaveAttribute('disabled') + }) + + it('should open previous page on click', async () => { + const tabs = getTabs(1) + remixMock.mockSearchParams(new URLSearchParams([['page', '2']])) + await renderTablePageLayout(tabs) + + await userEvent.click( + screen + .getByTestId(TestIds.Pagination) + .querySelector('[data-order=first]')!, + ) + + expect(remixMock.getLastSetParams()?.toString()).toEqual('page=1') + }) + + it('should disable next button on last page', async () => { + const tabs = getTabs(1) + remixMock.mockSearchParams(new URLSearchParams([['page', '3']])) + await renderTablePageLayout(tabs) + + await userEvent.click( + screen + .getByTestId(TestIds.Pagination) + .querySelector('[data-order=first]')!, + ) + + expect( + screen + .queryByTestId(TestIds.Pagination) + ?.querySelector('[data-order=last]'), + ).toHaveAttribute('disabled') + }) + + it('should change page on click', async () => { + const tabs = getTabs(1) + await renderTablePageLayout(tabs) + await userEvent.click(screen.getByText('3', { selector: 'li' })) + + expect(remixMock.getLastSetParams()?.toString()).toEqual('page=3') + }) +}) diff --git a/frontend/packages/data-portal/app/components/Tabs.tsx b/frontend/packages/data-portal/app/components/Tabs.tsx index f3531fced..cbf2fd44b 100644 --- a/frontend/packages/data-portal/app/components/Tabs.tsx +++ b/frontend/packages/data-portal/app/components/Tabs.tsx @@ -1,5 +1,6 @@ -import Tab from '@mui/material/Tab' -import MUITabs, { TabsProps } from '@mui/material/Tabs' +// TODO path imports not working in unit tests +// eslint-disable-next-line cryoet-data-portal/no-root-mui-import +import { Tab, Tabs as MUITabs, TabsProps } from '@mui/material' import { ReactNode } from 'react' import { cns } from 'app/utils/cns' diff --git a/frontend/packages/data-portal/app/mocks/LocalStorage.mock.ts b/frontend/packages/data-portal/app/mocks/LocalStorage.mock.ts new file mode 100644 index 000000000..712ebd6d9 --- /dev/null +++ b/frontend/packages/data-portal/app/mocks/LocalStorage.mock.ts @@ -0,0 +1,30 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import { jest } from '@jest/globals' + +export class LocalStorageMock { + setValue = jest.fn() + + useLocalStorageValue = jest.fn() + + constructor() { + jest.mock('@react-hookz/web', () => ({ + useLocalStorageValue: this.useLocalStorageValue, + })) + + this.reset() + } + + mockValue(value: string | null) { + this.useLocalStorageValue.mockReturnValue({ + set: this.setValue, + value, + }) + } + + reset() { + this.useLocalStorageValue.mockReturnValue({ + set: this.setValue, + value: null, + }) + } +} diff --git a/frontend/packages/data-portal/app/mocks/Remix.mock.ts b/frontend/packages/data-portal/app/mocks/Remix.mock.ts new file mode 100644 index 000000000..257acb5dc --- /dev/null +++ b/frontend/packages/data-portal/app/mocks/Remix.mock.ts @@ -0,0 +1,62 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import { jest } from '@jest/globals' + +const DEFAULT_PATHNAME = '/' + +type SetURLSearchParamsValue = + | URLSearchParams + | ((prev: URLSearchParams) => URLSearchParams) + +export class RemixMock { + useLocation = jest.fn() + + useNavigation = jest.fn() + + setParams = jest.fn() + + useSearchParams = jest.fn() + + constructor() { + jest.mock('@remix-run/react', () => ({ + Link: jest.fn(), + useLocation: this.useLocation, + useNavigation: this.useNavigation, + useSearchParams: this.useSearchParams, + })) + + this.reset() + } + + mockPathname(pathname: string) { + this.useLocation.mockReturnValue({ pathname }) + } + + mockSearchParams(value: URLSearchParams) { + this.useSearchParams.mockReturnValue([value, this.setParams]) + } + + getLastSetParams(prevParams = new URLSearchParams()) { + const setParams = this.setParams.mock.lastCall?.[0] as + | SetURLSearchParamsValue + | undefined + + const params = + typeof setParams === 'function' ? setParams(prevParams) : setParams + + return params + } + + reset() { + this.useLocation.mockReturnValue({ pathname: DEFAULT_PATHNAME }) + + this.useNavigation.mockReturnValue({ + state: 'idle', + }) + + this.setParams = jest.fn() + this.useSearchParams.mockReturnValue([ + new URLSearchParams(), + this.setParams, + ]) + } +} diff --git a/frontend/packages/data-portal/app/utils/mock.ts b/frontend/packages/data-portal/app/utils/mock.ts new file mode 100644 index 000000000..ee323043d --- /dev/null +++ b/frontend/packages/data-portal/app/utils/mock.ts @@ -0,0 +1,18 @@ +/* eslint-disable import/no-extraneous-dependencies */ + +import { jest } from '@jest/globals' +import userEvent from '@testing-library/user-event' + +export function setMockTime(time: string) { + jest.useFakeTimers().setSystemTime(new Date(time)) +} + +/** + * Util for getting mock user without a delay. This is required for tests that + * use fake timers, otherwise the test will hang indefinitely: + * + * https://github.com/testing-library/user-event/issues/833#issuecomment-1013632841 + */ +export function getMockUser() { + return userEvent.setup({ delay: null }) +} diff --git a/frontend/packages/data-portal/jest.config.cjs b/frontend/packages/data-portal/jest.config.cjs index b16426c25..a731aab92 100644 --- a/frontend/packages/data-portal/jest.config.cjs +++ b/frontend/packages/data-portal/jest.config.cjs @@ -8,6 +8,7 @@ module.exports = { moduleNameMapper: { '^app/(.*)$': '/app/$1', '^(.*).png$': '/app/utils/fileMock.ts', + '^(.*).module.css$': 'identity-obj-proxy', }, transform: { diff --git a/frontend/packages/data-portal/package.json b/frontend/packages/data-portal/package.json index 7c4098a3f..98a8b38b6 100644 --- a/frontend/packages/data-portal/package.json +++ b/frontend/packages/data-portal/package.json @@ -122,6 +122,7 @@ "eslint": "^8.51.0", "eslint-config-cryoet-data-portal": "workspace:*", "eslint-plugin-cryoet-data-portal": "workspace:*", + "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "playwright": "^1.41.2", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 4b80069ea..060818074 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -296,6 +296,9 @@ importers: eslint-plugin-cryoet-data-portal: specifier: workspace:* version: link:../eslint-plugin + identity-obj-proxy: + specifier: ^3.0.0 + version: 3.0.0 jest: specifier: ^29.7.0 version: 29.7.0(@types/node@20.8.4)(ts-node@10.9.1) @@ -7212,6 +7215,10 @@ packages: engines: {node: '>=6'} dev: true + /harmony-reflect@1.6.2: + resolution: {integrity: sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==} + dev: true + /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -7475,6 +7482,13 @@ packages: postcss: 8.4.31 dev: true + /identity-obj-proxy@3.0.0: + resolution: {integrity: sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==} + engines: {node: '>=4'} + dependencies: + harmony-reflect: 1.6.2 + dev: true + /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} From 79badba989083917689cf4ac867161b3970bcd16 Mon Sep 17 00:00:00 2001 From: Jeremy Asuncion Date: Thu, 2 Jan 2025 10:17:12 -0800 Subject: [PATCH 18/35] feat: preview label deployments (#1413) * preview label deployments * remove unnecessary condition --- .github/workflows/dev-deploy.yml | 153 +++++++++++++++++++++++++++---- 1 file changed, 133 insertions(+), 20 deletions(-) diff --git a/.github/workflows/dev-deploy.yml b/.github/workflows/dev-deploy.yml index 02d8df56a..b22834dd9 100644 --- a/.github/workflows/dev-deploy.yml +++ b/.github/workflows/dev-deploy.yml @@ -7,19 +7,61 @@ on: delete: branches: - 'dev-*' + pull_request: + types: [labeled, unlabeled, synchronize, closed] # https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services permissions: - id-token: write contents: read + id-token: write + pull-requests: write jobs: deploy-to-dev: name: deploy dev branch runs-on: ubuntu-latest environment: dev - if: github.repository == 'chanzuckerberg/cryoet-data-portal' + if: | + github.repository == 'chanzuckerberg/cryoet-data-portal' && ( + github.event_name != 'pull_request' || ( + startsWith(github.head_ref, 'dev-') != true && ( + contains(github.event.pull_request.labels.*.name, 'preview') || ( + github.event.action == 'unlabeled' && + github.event.label.name == 'preview' + ) + ) + ) + ) + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + + - id: deploy-data + name: get stack name + uses: actions/github-script@v7 + with: + result-encoding: string + script: | + const event = ${{ toJson(github.event) }} + const eventName = '${{ github.event_name }}' + + let name = '' + + switch (eventName) { + case 'pull_request': { + name = event.pull_request.head.ref + break + } + + default: { + name = event.ref.replace('refs/heads/', '') + break + } + } + + return name.replaceAll('/', '-').slice(0, 25) + - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: @@ -27,16 +69,15 @@ jobs: aws-region: ${{ secrets.AWS_REGION }} role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} role-duration-seconds: 1200 - - name: Setting up stack name - run: | - if [[ ${#GITHUB_REF_NAME} -gt 25 ]]; then - echo "branch name: ${GITHUB_REF_NAME}, length ${#GITHUB_REF_NAME}, is $((${#GITHUB_REF_NAME} - 25)) characters too long, please use a branch name that's 25 characters or shorter" - exit 1 - else - echo $GITHUB_REF_NAME | tr '[:upper:]' '[:lower:]' | xargs -I {} -n 1 echo STACK_NAME={} >> $GITHUB_ENV - fi + - name: Create or update dev stack - if: ${{ github.event_name == 'push' }} + if: | + github.event_name == 'push' || ( + github.event_name == 'pull_request' && ( + github.event.action == 'labeled' || + github.event.action == 'synchronize' + ) + ) uses: chanzuckerberg/github-actions/.github/actions/deploy-happy-stack@v1.24.0 env: # Force using BuildKit instead of normal Docker, required so that metadata @@ -46,7 +87,7 @@ jobs: DOCKER_REPO: ${{ secrets.ECR_REPO }}/ ENV: dev with: - stack-name: ${{ env.STACK_NAME }} + stack-name: ${{ steps.deploy-data.outputs.result }} create-tag: true tfe-token: ${{ secrets.TFE_TOKEN }} working-directory: ./frontend @@ -54,23 +95,95 @@ jobs: operation: create-or-update - name: Annotate workflow run with frontend URL - if: ${{ github.event_name == 'push' }} && success() + if: | + github.event_name == 'push' || ( + github.event_name == 'pull_request' && ( + github.event.action == 'labeled' || + github.event.action == 'synchronize' + ) + ) run: | echo "# Frontend URL:" >> $GITHUB_STEP_SUMMARY echo >> $GITHUB_STEP_SUMMARY - echo "https://${{ env.STACK_NAME }}.cryoet.dev.si.czi.technology" >> $GITHUB_STEP_SUMMARY + echo "https://${{ steps.deploy-data.outputs.result }}.cryoet.dev.si.czi.technology" >> $GITHUB_STEP_SUMMARY + + - id: find-comment + name: Find PR comment + if: github.event_name == 'pull_request' + uses: peter-evans/find-comment@v3 + with: + issue-number: ${{ github.event.pull_request.number }} + body-includes: 'Frontend Preview URL' + + - id: get-comment-date + name: Get PR comment updated date + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + result-encoding: string + script: | + const date = new Date() + + const options = { + month: '2-digit', + day: '2-digit', + year: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: true, + }; + + const pstDate = date.toLocaleString('en-US', { timeZone: 'America/Los_Angeles', ...options }); + return pstDate.replace(',', ' @'); + + - name: Post comment on PR + if: | + github.event_name == 'pull_request' && ( + github.event.action == 'labeled' || + github.event.action == 'synchronize' + ) + uses: peter-evans/create-or-update-comment@v4 + with: + comment-id: ${{ steps.find-comment.outputs.comment-id}} + issue-number: ${{ github.event.pull_request.number}} + edit-mode: replace + body: | + # Frontend Preview URL + + https://${{ steps.deploy-data.outputs.result }}.cryoet.dev.si.czi.technology + + Updated: ${{ steps.get-comment-date.outputs.result }} PST + + - name: Delete PR comment + if: | + github.event_name == 'pull_request' && ( + github.event.action == 'unlabeled' || + github.event.action == 'closed' + ) && + steps.find-comment.outputs.comment-id != '' + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.deleteComment({ + comment_id: ${{ steps.find-comment.outputs.comment-id }}, + owner: context.repo.owner, + repo: context.repo.repo, + }) - - name: Delete dev set up stack name - if: ${{ github.event_name == 'delete' && startsWith(github.event.ref, 'dev-') }} - run: | - echo ${{ github.event.ref }} | tr '[:upper:]' '[:lower:]' | xargs -I {} -n 1 echo DELETE_STACK_NAME={} >> $GITHUB_ENV - name: Delete dev - if: ${{ github.event_name == 'delete' && startsWith(github.event.ref, 'dev-') }} + if: | + github.event_name == 'delete' || ( + github.event_name == 'pull_request' && ( + github.event.action == 'unlabeled' || + github.event.action == 'closed' + ) + ) uses: chanzuckerberg/github-actions/.github/actions/deploy-happy-stack@v1.24.0 env: ENV: dev with: - stack-name: ${{ env.DELETE_STACK_NAME }} + stack-name: ${{ steps.deploy-data.outputs.result }} operation: delete tfe-token: ${{ secrets.TFE_TOKEN }} env: dev From 7d9d7c326017481d6d4f4db730c96c0c19d31cba Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 18:23:46 +0000 Subject: [PATCH 19/35] chore(main): release web 1.38.0 (#1410) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- frontend/CHANGELOG.md | 23 +++++++++++++++++++++++ frontend/package.json | 2 +- release-please.manifest.json | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index 04eda7522..d63909a34 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +## [1.38.0](https://github.com/chanzuckerberg/cryoet-data-portal/compare/web-v1.37.2...web-v1.38.0) (2025-01-02) + + +### ✨ Features + +* Add deposition to V2 run query ([#1424](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1424)) ([2632ac0](https://github.com/chanzuckerberg/cryoet-data-portal/commit/2632ac0b7f8ddedfce50dc8dfa4b2e0fc3b4fb9b)) +* Add diff logging for dataset page ([#1419](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1419)) ([4ee07f7](https://github.com/chanzuckerberg/cryoet-data-portal/commit/4ee07f7f183d7fed8dbdfb51f600cd90cb8825e9)) +* Add V2 query for dataset page ([#1409](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1409)) ([36ba07f](https://github.com/chanzuckerberg/cryoet-data-portal/commit/36ba07f8c650070caaa5e337b029b3666c8ae4db)) +* Finish converting run page query to V2 ([#1425](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1425)) ([c46b9e5](https://github.com/chanzuckerberg/cryoet-data-portal/commit/c46b9e537121e4b14a4ee6dbab21c123a04a215b)) +* Use some V2 fields in dataset page ([#1427](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1427)) ([bec698e](https://github.com/chanzuckerberg/cryoet-data-portal/commit/bec698e6a391012f82c9c482196bbe06ac5c25c6)) + + +### 🐞 Bug Fixes + +* Fix affine transformation matrix diff log ([#1422](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1422)) ([9b823e1](https://github.com/chanzuckerberg/cryoet-data-portal/commit/9b823e1fdb678df075e26209b28ad85287635cd7)) +* Fix more run page diff logs ([#1414](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1414)) ([78b8fa9](https://github.com/chanzuckerberg/cryoet-data-portal/commit/78b8fa98696c0f2a3668e2aacb691ef4f4e6f00c)) +* Fix run query diff logging ([#1405](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1405)) ([7179752](https://github.com/chanzuckerberg/cryoet-data-portal/commit/71797529b5114157979683aef35abcab9d014903)) + + +### 🧪 Tests + +* unit tests feature components ([#1423](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1423)) ([2473e30](https://github.com/chanzuckerberg/cryoet-data-portal/commit/2473e3029aa64ed5764afc516f4ae6184a276783)) + ## [1.37.2](https://github.com/chanzuckerberg/cryoet-data-portal/compare/web-v1.37.1...web-v1.37.2) (2024-12-17) diff --git a/frontend/package.json b/frontend/package.json index f65e9508e..b5c530ed3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "1.37.2", + "version": "1.38.0", "scripts": { "preinstall": "npx only-allow pnpm", "build": "pnpm -r build", diff --git a/release-please.manifest.json b/release-please.manifest.json index d58d4d757..6aea47e60 100644 --- a/release-please.manifest.json +++ b/release-please.manifest.json @@ -1,4 +1,4 @@ { - "frontend": "1.37.2", + "frontend": "1.38.0", "client/python/cryoet_data_portal": "4.3.0" } From f7754e4d88e20232f4456e61b51205727b90c1f8 Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Thu, 2 Jan 2025 13:29:35 -0800 Subject: [PATCH 20/35] feat: Use V2 aggregate data in run page (#1429) --- .../data-portal/app/hooks/useRunById.ts | 62 ++++++++++--------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/frontend/packages/data-portal/app/hooks/useRunById.ts b/frontend/packages/data-portal/app/hooks/useRunById.ts index 80c2d4c5e..138889ddd 100644 --- a/frontend/packages/data-portal/app/hooks/useRunById.ts +++ b/frontend/packages/data-portal/app/hooks/useRunById.ts @@ -40,40 +40,46 @@ export function useRunById() { return t2.id - t1.id }) - // TODO(bchu): Sort manually in V2. - const processingMethods = v1.tomograms_for_distinct_processing_methods.map( - (tomogram) => tomogram.processing, - ) - - const objectNames = v1.annotations_for_object_names.map( - (annotation) => annotation.object_name, - ) - - const objectShapeTypes = v1.annotation_files_for_shape_types.map( - (file) => file.shape_type, - ) - - const annotationSoftwares = v1.annotations_for_softwares - .map((annotation) => annotation.annotation_software) - .filter(isDefined) - - // TODO(bchu): Sort manually in V2. - const resolutions = v1.tomograms_for_resolutions.map( - (tomogram) => tomogram.voxel_spacing, - ) + const objectNames = + v2.uniqueObjectNames.aggregate + ?.map((aggregate) => aggregate.groupBy?.objectName) + .filter(isDefined) ?? [] + + const objectShapeTypes = + v2.uniqueShapeTypes.aggregate + ?.map((aggregate) => aggregate.groupBy?.shapeType) + .filter(isDefined) ?? [] + + const annotationSoftwares = + v2.uniqueAnnotationSoftwares.aggregate + ?.map((aggregate) => aggregate.groupBy?.annotationSoftware) + .filter(isDefined) ?? [] + + const resolutions = + v2.uniqueResolutions.aggregate + ?.map((aggregate) => aggregate.groupBy?.voxelSpacing) + .filter(isDefined) + .sort((resolutionA, resolutionB) => resolutionA - resolutionB) ?? [] + + const processingMethods = + v2.uniqueProcessingMethods.aggregate + ?.map((aggregate) => aggregate.groupBy?.processing) + .filter(isDefined) + .sort((processingMethodA, processingMethodB) => + processingMethodA.localeCompare(processingMethodB), + ) ?? [] const annotationFilesAggregates = { - totalCount: v1.annotation_files_aggregate_for_total.aggregate?.count ?? 0, - filteredCount: - v1.annotation_files_aggregate_for_filtered.aggregate?.count ?? 0, + totalCount: v2.numTotalAnnotationRows.aggregate?.[0].count ?? 0, + filteredCount: v2.numFilteredAnnotationRows.aggregate?.[0].count ?? 0, groundTruthCount: - v1.annotation_files_aggregate_for_ground_truth.aggregate?.count ?? 0, - otherCount: v1.annotation_files_aggregate_for_other.aggregate?.count ?? 0, + v2.numFilteredGroundTruthAnnotationRows.aggregate?.[0].count ?? 0, + otherCount: v2.numFilteredOtherAnnotationRows.aggregate?.[0].count ?? 0, } - const tomogramsCount = v1.tomograms_aggregate.aggregate?.count ?? 0 + const tomogramsCount = v2.tomogramsAggregate.aggregate?.[0].count ?? 0 - const alignmentsCount = v2.alignmentsAggregate.aggregate?.[0]?.count ?? 0 + const alignmentsCount = v2.alignmentsAggregate.aggregate?.[0].count ?? 0 const deposition = v2.depositions[0] From 531ece1e955f936893e72a3184d7da3d723c4ecf Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:16:38 -0800 Subject: [PATCH 21/35] chore: Remove Multiple Tomograms flag (#1434) * delete file * lint * tests --- .../ConfigureTomogramDownloadContent.tsx | 123 +----- .../Download/DownloadOptionsContent.tsx | 33 +- .../app/components/Radio/Radio.tsx | 9 +- .../components/Run/AnnotationOveriewTable.tsx | 45 +-- .../app/components/Run/RunHeader.tsx | 139 ++----- .../app/components/Run/RunMetadataDrawer.tsx | 9 +- .../Run/TomogramsMetadataSection.tsx | 74 ---- .../app/components/ViewTomogramButton.tsx | 18 +- .../data-portal/app/routes/runs.$id.tsx | 71 ++-- .../data-portal/app/utils/featureFlags.ts | 3 +- .../data-portal/e2e/downloadDialog.test.ts | 357 +----------------- .../data-portal/e2e/metadataDrawer.test.ts | 30 +- .../downloadDialog/downloadDialogActor.ts | 18 - .../e2e/pageObjects/downloadDialog/utils.ts | 18 +- .../e2e/pageObjects/metadataDrawer/utils.ts | 46 +-- 15 files changed, 147 insertions(+), 846 deletions(-) delete mode 100644 frontend/packages/data-portal/app/components/Run/TomogramsMetadataSection.tsx diff --git a/frontend/packages/data-portal/app/components/Download/ConfigureTomogramDownloadContent.tsx b/frontend/packages/data-portal/app/components/Download/ConfigureTomogramDownloadContent.tsx index 3c6418f2b..fbe9db468 100644 --- a/frontend/packages/data-portal/app/components/Download/ConfigureTomogramDownloadContent.tsx +++ b/frontend/packages/data-portal/app/components/Download/ConfigureTomogramDownloadContent.tsx @@ -1,18 +1,16 @@ import { Callout, CalloutTitle } from '@czi-sds/components' import RadioGroup from '@mui/material/RadioGroup' -import { useCallback, useMemo } from 'react' +import { useCallback } from 'react' import { match } from 'ts-pattern' import { CopyBox } from 'app/components/CopyBox' import { I18n } from 'app/components/I18n' import { Radio } from 'app/components/Radio' -import { Select, SelectOption } from 'app/components/Select' import { useDownloadModalContext } from 'app/context/DownloadModal.context' import { useDownloadModalQueryParamState } from 'app/hooks/useDownloadModalQueryParamState' import { useI18n } from 'app/hooks/useI18n' import { useLogPlausibleCopyEvent } from 'app/hooks/useLogPlausibleCopyEvent' import { DownloadConfig } from 'app/types/download' -import { useFeatureFlag } from 'app/utils/featureFlags' import { FileFormatDropdown } from './FileFormatDropdown' import { TomogramSelector } from './Tomogram/TomogramSelector' @@ -20,19 +18,12 @@ import { TomogramSelector } from './Tomogram/TomogramSelector' const TOMOGRAM_FILE_FORMATS = ['mrc', 'zarr'] export function ConfigureTomogramDownloadContent() { - const multipleTomogramsEnabled = useFeatureFlag('multipleTomograms') - const { t } = useI18n() const { downloadConfig, - tomogramProcessing, - tomogramSampling, setAllAnnotationsConfig, - setTomogramConfigDeprecated, setTomogramConfig, - setTomogramProcessing, - setTomogramSampling, setTomogramId, } = useDownloadModalQueryParamState() @@ -40,47 +31,12 @@ export function ConfigureTomogramDownloadContent() { tomogramToDownload, allAnnotationFiles = [], allTomograms = [], - allTomogramProcessing = [], runId, } = useDownloadModalContext() - const tomogramSamplingOptions = useMemo( - () => - allTomograms.map((tomogram) => ({ - key: t('unitAngstrom', { value: tomogram.voxelSpacing }), - value: `(${tomogram.sizeX}, ${tomogram.sizeY}, ${tomogram.sizeZ})px`, - })), - [allTomograms, t], - ) - - const tomogramProcessingOptions = useMemo( - () => - allTomogramProcessing.map((processing) => ({ - key: processing, - value: processing, - })), - [allTomogramProcessing], - ) - const setTomogramConfigWithInitialValues = useCallback(() => { - if (multipleTomogramsEnabled) { - setTomogramConfig(allTomograms[0]?.id.toString()) - return - } - - const tomogram = allTomograms.at(0) - const processing = allTomogramProcessing.at(0) - - if (tomogram && processing) { - setTomogramConfigDeprecated(`${tomogram.voxelSpacing}`, processing) - } - }, [ - allTomogramProcessing, - allTomograms, - setTomogramConfigDeprecated, - setTomogramConfig, - multipleTomogramsEnabled, - ]) + setTomogramConfig(allTomograms[0]?.id.toString()) + }, [allTomograms, setTomogramConfig]) const { logPlausibleCopyEvent } = useLogPlausibleCopyEvent() @@ -106,64 +62,21 @@ export function ConfigureTomogramDownloadContent() { >
- {multipleTomogramsEnabled ? ( - - ) : ( - <> - - - )} +
@@ -206,11 +119,9 @@ export function ConfigureTomogramDownloadContent() { )} - {multipleTomogramsEnabled && ( - - - - )} + + + ) } diff --git a/frontend/packages/data-portal/app/components/Download/DownloadOptionsContent.tsx b/frontend/packages/data-portal/app/components/Download/DownloadOptionsContent.tsx index 161f848eb..cba44a8e1 100644 --- a/frontend/packages/data-portal/app/components/Download/DownloadOptionsContent.tsx +++ b/frontend/packages/data-portal/app/components/Download/DownloadOptionsContent.tsx @@ -15,7 +15,6 @@ import { useDownloadModalQueryParamState } from 'app/hooks/useDownloadModalQuery import { useI18n } from 'app/hooks/useI18n' import { DownloadConfig, DownloadTab } from 'app/types/download' import { checkExhaustive } from 'app/types/utils' -import { useFeatureFlag } from 'app/utils/featureFlags' import { getTomogramName } from 'app/utils/tomograms' import { I18n } from '../I18n' @@ -35,13 +34,11 @@ const DOWNLOAD_TAB_MAP: Record = { } export function DownloadOptionsContent() { - const multipleTomogramsEnabled = useFeatureFlag('multipleTomograms') const { t } = useI18n() const { downloadTab, setDownloadTab, downloadConfig, - tomogramProcessing, tomogramSampling, annotationId, referenceTomogramId, @@ -74,7 +71,7 @@ export function DownloadOptionsContent() { <> {runName && } - {multipleTomogramsEnabled && tomogramToDownload !== undefined && ( + {tomogramToDownload !== undefined && ( <> )} - {multipleTomogramsEnabled && referenceTomogram !== undefined && ( + {referenceTomogram !== undefined && ( )} - {!multipleTomogramsEnabled && tomogramSampling && tomogramToDownload && ( + {annotationToDownload && tomogramToDownload?.alignment && ( - )} - {!multipleTomogramsEnabled && tomogramProcessing && ( - )} - {multipleTomogramsEnabled && - annotationToDownload && - tomogramToDownload?.alignment && ( - - )} {annotationToDownload && ( - {multipleTomogramsEnabled && - annotationToDownload !== undefined && - tomogramToDownload?.alignment ? ( + {annotationToDownload !== undefined && tomogramToDownload?.alignment ? (
-
+
@@ -97,30 +96,26 @@ export function AnnotationOverviewTable() { label: t('lastModifiedDate'), values: [annotation.last_modified_date ?? '--'], }, - ...(multipleTomogramsEnabled - ? [ - { - label: t('alignmentId'), - labelExtra: ( - } - placement="top" - > - - - ), - values: [ - v2AnnotationShape?.annotationFiles.edges.at(0)?.node - .alignmentId ?? '--', - ], - }, - ] - : []), + { + label: t('alignmentId'), + labelExtra: ( + } + placement="top" + > + + + ), + values: [ + v2AnnotationShape?.annotationFiles.edges.at(0)?.node.alignmentId ?? + '--', + ], + }, { label: t('methodType'), values: [annotation.method_type ?? '--'], diff --git a/frontend/packages/data-portal/app/components/Run/RunHeader.tsx b/frontend/packages/data-portal/app/components/Run/RunHeader.tsx index 201e5e0fc..ac30cda93 100644 --- a/frontend/packages/data-portal/app/components/Run/RunHeader.tsx +++ b/frontend/packages/data-portal/app/components/Run/RunHeader.tsx @@ -1,5 +1,4 @@ import { Button, Icon } from '@czi-sds/components' -import { match, P } from 'ts-pattern' import { Breadcrumbs } from 'app/components/Breadcrumbs' import { CollapsibleList } from 'app/components/CollapsibleList' @@ -21,29 +20,9 @@ import { import { useRunById } from 'app/hooks/useRunById' import { i18n } from 'app/i18n' import { TableDataValue } from 'app/types/table' -import { useFeatureFlag } from 'app/utils/featureFlags' import { getTiltRangeLabel } from 'app/utils/tiltSeries' -interface FileSummaryData { - key: string - value: number -} - -function FileSummary({ data }: { data: FileSummaryData[] }) { - const { t } = useI18n() - return ( - ({ - key, - value: t('fileCount', { count: value }), - }))} - /> - ) -} - export function RunHeader() { - const multipleTomogramsEnabled = useFeatureFlag('multipleTomograms') const { run, processingMethods, @@ -67,11 +46,6 @@ export function RunHeader() { (currentTomogram) => currentTomogram.isVisualizationDefault, ) ?? tomograms.at(0) - const keyPhotoURL = - (multipleTomogramsEnabled - ? tomogramV2?.keyPhotoUrl - : tomogram?.key_photo_url) ?? undefined - const neuroglancerConfig = tomogramV2?.neuroglancerConfig const { openRunDownloadModal } = useDownloadModalQueryParamState() @@ -85,20 +59,7 @@ export function RunHeader() { actions={
tomogramV2Id.toString(), - ) - .with( - { multipleTomogramsEnabled: false, tomogramV1Id: P.number }, - ({ tomogramV1Id }) => tomogramV1Id.toString(), - ) - .otherwise(() => undefined)} + tomogramId={tomogramV2?.id?.toString()} neuroglancerConfig={neuroglancerConfig} buttonProps={{ sdsStyle: 'rounded', @@ -140,71 +101,51 @@ export function RunHeader() { title={run.name} renderHeader={({ moreInfo }) => (
- +
{t('runOverview')} - {multipleTomogramsEnabled ? ( - 0 ? t('available') : t('notSubmitted'), - valueClass: - framesCount > 0 - ? undefined - : 'text-sds-color-primitive-gray-500', - }, - { - key: t('tiltSeries'), - value: - tiltSeriesCount > 0 ? t('available') : t('notSubmitted'), - valueClass: - tiltSeriesCount > 0 - ? undefined - : 'text-sds-color-primitive-gray-500', - }, - { - key: t('alignment'), - value: - alignmentsCount > 0 ? t('available') : t('notSubmitted'), - }, - { - key: t('tomograms'), - value: tomogramsCount.toString(), - }, - { - key: t('annotations'), - value: annotationsCount.toString(), - }, - ]} - /> - ) : ( - - )} + 0 ? t('available') : t('notSubmitted'), + valueClass: + framesCount > 0 + ? undefined + : 'text-sds-color-primitive-gray-500', + }, + { + key: t('tiltSeries'), + value: + tiltSeriesCount > 0 ? t('available') : t('notSubmitted'), + valueClass: + tiltSeriesCount > 0 + ? undefined + : 'text-sds-color-primitive-gray-500', + }, + { + key: t('alignment'), + value: + alignmentsCount > 0 ? t('available') : t('notSubmitted'), + }, + { + key: t('tomograms'), + value: tomogramsCount.toString(), + }, + { + key: t('annotations'), + value: annotationsCount.toString(), + }, + ]} + />
- {multipleTomogramsEnabled ? ( - - ) : ( - - )} + ) } diff --git a/frontend/packages/data-portal/app/components/Run/TomogramsMetadataSection.tsx b/frontend/packages/data-portal/app/components/Run/TomogramsMetadataSection.tsx deleted file mode 100644 index 41da8fb69..000000000 --- a/frontend/packages/data-portal/app/components/Run/TomogramsMetadataSection.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { AccordionMetadataTable } from 'app/components/AccordionMetadataTable' -import { useRunById } from 'app/hooks/useRunById' -import { i18n } from 'app/i18n' -import { getTableData } from 'app/utils/table' -import { isFiducial } from 'app/utils/tomograms' - -import { IDENTITY_MATRIX_4X4, Matrix4x4 } from './Matrix4x4' - -export function TomogramsMetadataSection() { - const { run } = useRunById() - - const tomo = run.tomogram_voxel_spacings.at(0)?.tomograms.at(0) - - if (!tomo) { - return null - } - - const tomogramsTableData = getTableData( - { - label: i18n.reconstructionSoftware, - values: [tomo.reconstruction_software], - }, - { - label: i18n.reconstructionMethod, - values: [tomo.reconstruction_method], - className: 'capitalize', - }, - { - label: i18n.processingSoftware, - values: [tomo.processing_software ?? ''], - }, - { - label: i18n.availableProcessing, - values: [tomo.processing], - className: 'capitalize', - }, - { - label: i18n.smallestAvailableVoxelSpacing, - values: [i18n.unitAngstrom(+tomo.voxel_spacing)], - }, - { - label: `${i18n.size} (x, y, z)`, - values: [`(${tomo.size_x}, ${tomo.size_y}, ${tomo.size_z}) px`], - }, - { - label: i18n.fiducialAlignmentStatus, - values: [ - isFiducial(tomo.fiducial_alignment_status) ? i18n.true : i18n.false, - ], - }, - { - label: i18n.ctfCorrected, - values: [tomo.ctf_corrected ? i18n.yes : i18n.no], - }, - { - label: i18n.affineTransformationMatrix, - values: [ - tomo.affine_transformation_matrix?.flat().join(' ') ?? - IDENTITY_MATRIX_4X4, - ], - renderValue: (value: string) => { - return - }, - }, - ) - - return ( - - ) -} diff --git a/frontend/packages/data-portal/app/components/ViewTomogramButton.tsx b/frontend/packages/data-portal/app/components/ViewTomogramButton.tsx index 0c3008f34..4bcab9f74 100644 --- a/frontend/packages/data-portal/app/components/ViewTomogramButton.tsx +++ b/frontend/packages/data-portal/app/components/ViewTomogramButton.tsx @@ -3,7 +3,6 @@ import { Button, ButtonProps, TooltipProps } from '@czi-sds/components' import { IdPrefix } from 'app/constants/idPrefixes' import { useI18n } from 'app/hooks/useI18n' import { EventPayloads, Events, usePlausible } from 'app/hooks/usePlausible' -import { useFeatureFlag } from 'app/utils/featureFlags' import { getNeuroglancerUrl } from 'app/utils/url' import { Link } from './Link' @@ -27,7 +26,6 @@ export function ViewTomogramButton({ tooltipPlacement, setIsHoveringOver, }: ViewTomogramButtonProps) { - const multipleTomogramsEnabled = useFeatureFlag('multipleTomograms') const plausible = usePlausible() const { t } = useI18n() @@ -36,18 +34,16 @@ export function ViewTomogramButton({ } const enabled = tomogramId !== undefined && neuroglancerConfig != null - const enabledTooltipText = multipleTomogramsEnabled - ? t('viewTomogramInNeuroglancer', { - id: `${IdPrefix.Tomogram}-${tomogramId}`, - }) - : undefined - const disabledTooltipText = multipleTomogramsEnabled - ? t('noTomogramsAvailable') - : t('noTomogramAvailable') return ( - multipleTomogramsEnabled - ? tomogram.id === Number(tomogramId) - : `${tomogram.voxelSpacing}` === tomogramSampling && - tomogram.processing === tomogramProcessing, - ) + ? tomograms.find((tomogram) => tomogram.id === Number(tomogramId)) : undefined const tomogram = run.tomogram_voxel_spacings.at(0) @@ -172,7 +163,7 @@ export default function RunByIdPage() { return ( } - tabsTitle={multipleTomogramsEnabled ? t('browseRunData') : undefined} + tabsTitle={t('browseRunData')} banner={ depositionId && deposition && ( @@ -220,37 +211,33 @@ export default function RunByIdPage() { ), noFilteredResults: , }, - ...(multipleTomogramsEnabled - ? [ - { - title: t('tomograms'), - table: , - pageQueryParamKey: QueryParams.TomogramsPage, - filteredCount: tomogramsCount, - totalCount: tomogramsCount, - countLabel: t('tomograms'), - noTotalResults: ( - { - openRunDownloadModal({ - runId: run.id, - datasetId: run.dataset.id, - }) - }, - }, - ]} - /> - ), - }, - ] - : []), + { + title: t('tomograms'), + table: , + pageQueryParamKey: QueryParams.TomogramsPage, + filteredCount: tomogramsCount, + totalCount: tomogramsCount, + countLabel: t('tomograms'), + noTotalResults: ( + { + openRunDownloadModal({ + runId: run.id, + datasetId: run.dataset.id, + }) + }, + }, + ]} + /> + ), + }, ]} downloadModal={ = { depositions: ['local', 'dev', 'staging', 'prod'], - multipleTomograms: ['local', 'dev', 'staging', 'prod'], } const ENABLE_FEATURE_PARAM = 'enable-feature' diff --git a/frontend/packages/data-portal/e2e/downloadDialog.test.ts b/frontend/packages/data-portal/e2e/downloadDialog.test.ts index 87524848b..c02c7d252 100644 --- a/frontend/packages/data-portal/e2e/downloadDialog.test.ts +++ b/frontend/packages/data-portal/e2e/downloadDialog.test.ts @@ -10,7 +10,6 @@ import { SINGLE_DATASET_URL, SINGLE_RUN_URL, translations } from './constants' import { DownloadDialogActor } from './pageObjects/downloadDialog/downloadDialogActor' import { ANNOTATION_NON_STANDARD_TOMOGRAM_DOWNLOAD_TABS, - ANNOTATION_STANDARD_TOMOGRAM_DOWNLOAD_TABS, SINGLE_DATASET_DOWNLOAD_TABS, TOMOGRAM_DOWNLOAD_TABS, } from './pageObjects/downloadDialog/types' @@ -32,9 +31,7 @@ test.describe('downloadDialog', () => { test.describe('Single Dataset', () => { test('should open when clicking download button', async () => { - await downloadDialogPage.goTo( - `${SINGLE_DATASET_URL}?disable-feature=multipleTomograms`, - ) + await downloadDialogPage.goTo(SINGLE_DATASET_URL) await downloadDialogPage.openDialog(translations.downloadDataset) await downloadDialogActor.expectDialogToBeOpen({ @@ -47,9 +44,7 @@ test.describe('downloadDialog', () => { }) test('should display correct content', async () => { - await downloadDialogPage.goTo( - `${SINGLE_DATASET_URL}?disable-feature=multipleTomograms`, - ) + await downloadDialogPage.goTo(SINGLE_DATASET_URL) await downloadDialogPage.openDialog(translations.downloadDataset) await downloadDialogActor.expectDownloadDatasetDialogToShowCorrectContent( @@ -193,9 +188,7 @@ test.describe('downloadDialog', () => { test.describe('Single Run', () => { test('should open when clicking download button', async () => { - await downloadDialogPage.goTo( - `${SINGLE_RUN_URL}?disable-feature=multipleTomograms`, - ) + await downloadDialogPage.goTo(SINGLE_RUN_URL) await downloadDialogPage.openDialog(translations.download) await downloadDialogActor.expectDialogToBeOpen({ @@ -505,215 +498,11 @@ test.describe('downloadDialog', () => { }) }) - test.describe('Download Tomogram - multiple tomograms off', () => { - test('should select on click', async () => { - await downloadDialogActor.goToDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - step: DownloadStep.Configure, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.configureDownload, - }) - - await downloadDialogPage.clickDialogRadio(translations.downloadTomogram) - - await downloadDialogPage.expectRadioToBeSelected( - DownloadConfig.Tomogram, - ) - - await downloadDialogActor.expectTomogramDialogUrlToMatch({ - baseUrl: SINGLE_RUN_URL, - client, - step: DownloadStep.Configure, - config: DownloadConfig.Tomogram, - fileFormat: 'mrc', - }) - }) - - test('should select from url', async () => { - await downloadDialogActor.goToTomogramDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - config: DownloadConfig.Tomogram, - step: DownloadStep.Configure, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.configureDownload, - }) - - await downloadDialogPage.expectRadioToBeSelected( - DownloadConfig.Tomogram, - ) - }) - - test('should change selection on click', async () => { - await downloadDialogActor.goToDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - config: DownloadConfig.AllAnnotations, - step: DownloadStep.Configure, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.configureDownload, - }) - - await downloadDialogPage.clickDialogRadio(translations.downloadTomogram) - - await downloadDialogPage.expectRadioToBeSelected( - DownloadConfig.Tomogram, - ) - - await downloadDialogActor.expectTomogramDialogUrlToMatch({ - baseUrl: SINGLE_RUN_URL, - client, - step: DownloadStep.Configure, - config: DownloadConfig.Tomogram, - fileFormat: 'mrc', - }) - }) - - test.describe('should open tabs from url', () => { - TOMOGRAM_DOWNLOAD_TABS.forEach((tab) => { - test(`should open ${tab} tab from url`, async () => { - await downloadDialogActor.goToTomogramDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - config: DownloadConfig.Tomogram, - step: DownloadStep.Download, - fileFormat: 'mrc', - tab, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.downloadOptions, - }) - - await downloadDialogActor.expectDialogToBeOnCorrectTab({ - tab, - tabGroup: TOMOGRAM_DOWNLOAD_TABS, - }) - }) - }) - }) - - test.describe('should change tabs on click', () => { - const testCases = TOMOGRAM_DOWNLOAD_TABS.flatMap((v1, i) => - TOMOGRAM_DOWNLOAD_TABS.toSpliced(i, 1).map((v2) => ({ - fromTab: v1, - toTab: v2, - })), - ) - testCases.forEach(({ fromTab, toTab }) => { - test(`should change from ${fromTab} to ${toTab} on click`, async () => { - await downloadDialogActor.goToTomogramDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - config: DownloadConfig.Tomogram, - fileFormat: 'mrc', - step: DownloadStep.Download, - tab: fromTab, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.downloadOptions, - }) - - await downloadDialogPage.clickTab(toTab) - - await downloadDialogActor.expectDialogToBeOnCorrectTab({ - tab: toTab, - tabGroup: TOMOGRAM_DOWNLOAD_TABS, - }) - await downloadDialogActor.expectTomogramDialogUrlToMatch({ - baseUrl: SINGLE_RUN_URL, - client, - config: DownloadConfig.Tomogram, - fileFormat: 'mrc', - step: DownloadStep.Download, - tab: toTab, - }) - }) - }) - }) - - test.describe('should copy from tabs', () => { - const testCases = TOMOGRAM_DOWNLOAD_TABS.filter( - (tab) => tab !== DownloadTab.Download, - ) - - testCases.forEach((tab) => { - test(`should copy from ${tab} tab`, async ({ browserName }) => { - skipClipboardTestsForWebkit(browserName) - - await downloadDialogActor.goToTomogramDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - config: DownloadConfig.Tomogram, - fileFormat: 'mrc', - step: DownloadStep.Download, - tab, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.downloadOptions, - }) - - await downloadDialogPage.clickCopyButton() - - await downloadDialogActor.expectClipboardToHaveCorrectDownloadTomogramCommand( - { client, fileFormat: 'mrc', tab }, - ) - }) - }) - }) - - test('should close when x button clicked', async () => { - await downloadDialogActor.goToTomogramDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - config: DownloadConfig.Tomogram, - fileFormat: 'mrc', - step: DownloadStep.Download, - tab: DownloadTab.AWS, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.downloadOptions, - }) - - await downloadDialogPage.clickXButton() - - await downloadDialogPage.expectDialogToBeHidden() - }) - - test('should close when close button clicked', async () => { - await downloadDialogActor.goToTomogramDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - config: DownloadConfig.Tomogram, - fileFormat: 'mrc', - step: DownloadStep.Download, - tab: DownloadTab.AWS, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.downloadOptions, - }) - - await downloadDialogPage.clickCloseButton() - - await downloadDialogPage.expectDialogToBeHidden() - }) - }) - - test.describe('Download Tomogram - multiple tomograms on', () => { + test.describe('Download Tomogram', () => { test('should select on click', async () => { await downloadDialogActor.goToDownloadDialogUrl({ baseUrl: SINGLE_RUN_URL, step: DownloadStep.Configure, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -732,7 +521,6 @@ test.describe('downloadDialog', () => { step: DownloadStep.Configure, config: DownloadConfig.Tomogram, fileFormat: 'mrc', - multipleTomograms: true, }) }) @@ -742,7 +530,6 @@ test.describe('downloadDialog', () => { client, config: DownloadConfig.Tomogram, step: DownloadStep.Configure, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -759,7 +546,6 @@ test.describe('downloadDialog', () => { baseUrl: SINGLE_RUN_URL, config: DownloadConfig.AllAnnotations, step: DownloadStep.Configure, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -778,7 +564,6 @@ test.describe('downloadDialog', () => { step: DownloadStep.Configure, config: DownloadConfig.Tomogram, fileFormat: 'mrc', - multipleTomograms: true, }) }) @@ -786,9 +571,7 @@ test.describe('downloadDialog', () => { const lastTomogramId = ( await fetchTestSingleRun(client) ).data.tomograms.at(-1)!.id - await downloadDialogPage.goTo( - `${SINGLE_RUN_URL}?enable-feature=multipleTomograms`, - ) + await downloadDialogPage.goTo(SINGLE_RUN_URL) await page .locator(`button:has-text("${translations.tomograms}")`) .click() @@ -808,9 +591,7 @@ test.describe('downloadDialog', () => { // TODO(bchu): Add tomogram selector test. test('should change file type', async () => { - await downloadDialogPage.goTo( - `${SINGLE_RUN_URL}?enable-feature=multipleTomograms`, - ) + await downloadDialogPage.goTo(SINGLE_RUN_URL) await downloadDialogPage.openDialog( translations.downloadWithAdditionalOptions, ) @@ -838,7 +619,6 @@ test.describe('downloadDialog', () => { step: DownloadStep.Download, fileFormat: 'mrc', tab, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -869,7 +649,6 @@ test.describe('downloadDialog', () => { fileFormat: 'mrc', step: DownloadStep.Download, tab: fromTab, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -889,7 +668,6 @@ test.describe('downloadDialog', () => { fileFormat: 'mrc', step: DownloadStep.Download, tab: toTab, - multipleTomograms: true, }) }) }) @@ -911,7 +689,6 @@ test.describe('downloadDialog', () => { fileFormat: 'mrc', step: DownloadStep.Download, tab, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -935,7 +712,6 @@ test.describe('downloadDialog', () => { fileFormat: 'mrc', step: DownloadStep.Download, tab: DownloadTab.AWS, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -955,7 +731,6 @@ test.describe('downloadDialog', () => { fileFormat: 'mrc', step: DownloadStep.Download, tab: DownloadTab.AWS, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -968,120 +743,7 @@ test.describe('downloadDialog', () => { }) }) - test.describe('Download Annotation - multiple tomograms off', () => { - test('should select from url', async () => { - const { data } = await fetchTestSingleRun(client) - const annotationFile = data.annotation_files[0] - await downloadDialogActor.goToAnnotationDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - step: DownloadStep.Configure, - multipleTomograms: false, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.configureDownload, - }) - await expect(downloadDialogPage.getDialog()).toContainText( - annotationFile.format, - ) - }) - - test.describe('should open tabs from url', () => { - ANNOTATION_STANDARD_TOMOGRAM_DOWNLOAD_TABS.forEach((tab) => { - test(`should open ${tab} tab from url`, async () => { - await downloadDialogActor.goToAnnotationDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - step: DownloadStep.Download, - tab, - multipleTomograms: false, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.downloadOptions, - }) - - await downloadDialogActor.expectDialogToBeOnCorrectTab({ - tab, - tabGroup: ANNOTATION_STANDARD_TOMOGRAM_DOWNLOAD_TABS, - }) - }) - }) - }) - - test.describe('should change tabs on click', () => { - const testCases = ANNOTATION_STANDARD_TOMOGRAM_DOWNLOAD_TABS.flatMap( - (v1, i) => - ANNOTATION_STANDARD_TOMOGRAM_DOWNLOAD_TABS.toSpliced(i, 1).map( - (v2) => ({ - fromTab: v1, - toTab: v2, - }), - ), - ) - testCases.forEach(({ fromTab, toTab }) => { - test(`should change from ${fromTab} to ${toTab} on click`, async () => { - await downloadDialogActor.goToAnnotationDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - step: DownloadStep.Download, - tab: fromTab, - multipleTomograms: false, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.downloadOptions, - }) - - await downloadDialogPage.clickTab(toTab) - - await downloadDialogActor.expectDialogToBeOnCorrectTab({ - tab: toTab, - tabGroup: ANNOTATION_STANDARD_TOMOGRAM_DOWNLOAD_TABS, - }) - await downloadDialogActor.expectAnnotationDialogUrlToMatch({ - baseUrl: SINGLE_RUN_URL, - client, - step: DownloadStep.Download, - tab: toTab, - }) - }) - }) - }) - - test.describe('should copy from tabs', () => { - const testCases = ANNOTATION_STANDARD_TOMOGRAM_DOWNLOAD_TABS.filter( - (tab) => tab !== DownloadTab.Download, - ) - - testCases.forEach((tab) => { - test(`should copy from ${tab} tab`, async ({ browserName }) => { - skipClipboardTestsForWebkit(browserName) - - await downloadDialogActor.goToAnnotationDownloadDialogUrl({ - baseUrl: SINGLE_RUN_URL, - client, - step: DownloadStep.Download, - tab, - multipleTomograms: false, - }) - - await downloadDialogActor.expectDialogToBeOpen({ - title: translations.downloadOptions, - }) - - await downloadDialogPage.clickCopyButton() - - await downloadDialogActor.expectClipboardToHaveCorrectDownloadAnnotationCommand( - { client, tab }, - ) - }) - }) - }) - }) - - test.describe('Download Annotation - multiple tomograms on', () => { + test.describe('Download Annotation', () => { test('should select from url', async () => { const { data } = await fetchTestSingleRun(client) const annotationFile = data.annotation_files[0] @@ -1089,7 +751,6 @@ test.describe('downloadDialog', () => { baseUrl: SINGLE_RUN_URL, client, step: DownloadStep.Configure, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -1108,7 +769,6 @@ test.describe('downloadDialog', () => { client, step: DownloadStep.Download, tab, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -1140,7 +800,6 @@ test.describe('downloadDialog', () => { client, step: DownloadStep.Download, tab: fromTab, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ @@ -1158,7 +817,6 @@ test.describe('downloadDialog', () => { client, step: DownloadStep.Download, tab: toTab, - multipleTomograms: true, }) }) }) @@ -1178,7 +836,6 @@ test.describe('downloadDialog', () => { client, step: DownloadStep.Download, tab, - multipleTomograms: true, }) await downloadDialogActor.expectDialogToBeOpen({ diff --git a/frontend/packages/data-portal/e2e/metadataDrawer.test.ts b/frontend/packages/data-portal/e2e/metadataDrawer.test.ts index 0bebf070f..169a0d79f 100644 --- a/frontend/packages/data-portal/e2e/metadataDrawer.test.ts +++ b/frontend/packages/data-portal/e2e/metadataDrawer.test.ts @@ -81,35 +81,11 @@ test.describe('Metadata Drawer', () => { test('metadata should have correct data', async ({ page }) => { const metadataDrawerPage = new MetadataDrawerPage(page) - await metadataDrawerPage.goTo( - `${SINGLE_RUN_URL}?disable-feature=multipleTomograms`, - ) - await metadataDrawerPage.openViewAllInfoDrawer() - await metadataDrawerPage.waitForMetadataDrawerToBeVisible() - - const data = await getSingleRunTestMetadata( - client, - /* multipleTomogramsEnabled */ false, - ) - await metadataDrawerPage.expectMetadataDrawerToShowTitle(data.title) - await metadataDrawerPage.expandAllAccordions() - await metadataDrawerPage.expectMetadataTableCellsToDisplayValues(data) - }) - - test('metadata should have correct data - multipleTomograms on', async ({ - page, - }) => { - const metadataDrawerPage = new MetadataDrawerPage(page) - await metadataDrawerPage.goTo( - `${SINGLE_RUN_URL}?enable-feature=multipleTomograms`, - ) + await metadataDrawerPage.goTo(SINGLE_RUN_URL) await metadataDrawerPage.openViewAllInfoDrawer() await metadataDrawerPage.waitForMetadataDrawerToBeVisible() - const data = await getSingleRunTestMetadata( - client, - /* multipleTomogramsEnabled */ true, - ) + const data = await getSingleRunTestMetadata(client) await metadataDrawerPage.expectMetadataDrawerToShowTitle(data.title) await metadataDrawerPage.expandAllAccordions() await metadataDrawerPage.expectMetadataTableCellsToDisplayValues(data) @@ -151,7 +127,7 @@ test.describe('Metadata Drawer', () => { }) test.describe(`Tomogram Metadata: ${SINGLE_RUN_PATH}`, () => { - const url = `${SINGLE_RUN_URL}?table-tab=Tomograms&enable-feature=multipleTomograms` + const url = `${SINGLE_RUN_URL}?table-tab=Tomograms` test('should open metadata drawer', async ({ page }) => { const metadataDrawerPage = new MetadataDrawerPage(page) diff --git a/frontend/packages/data-portal/e2e/pageObjects/downloadDialog/downloadDialogActor.ts b/frontend/packages/data-portal/e2e/pageObjects/downloadDialog/downloadDialogActor.ts index c37619904..1affe9183 100644 --- a/frontend/packages/data-portal/e2e/pageObjects/downloadDialog/downloadDialogActor.ts +++ b/frontend/packages/data-portal/e2e/pageObjects/downloadDialog/downloadDialogActor.ts @@ -37,7 +37,6 @@ export class DownloadDialogActor { tab, annotationFile, tomogram, - multipleTomograms, }: { config?: DownloadConfig fileFormat?: string @@ -46,7 +45,6 @@ export class DownloadDialogActor { tab?: DownloadTab annotationFile?: { annotation: { id: string }; shape_type: string } tomogram?: { id: number; sampling: number; processing: string } - multipleTomograms?: boolean }) { const expectedUrl = constructDialogUrl(baseUrl, { config, @@ -55,7 +53,6 @@ export class DownloadDialogActor { tab, annotationFile, tomogram, - multipleTomograms, }) await this.downloadDialogPage.goTo(expectedUrl.href) } @@ -67,7 +64,6 @@ export class DownloadDialogActor { baseUrl, step, tab, - multipleTomograms, }: { client: ApolloClient config?: DownloadConfig @@ -75,7 +71,6 @@ export class DownloadDialogActor { baseUrl: string step?: DownloadStep tab?: DownloadTab - multipleTomograms?: boolean }) { const { data } = await fetchTestSingleRun(client) const tomogram = data.tomograms[0] @@ -91,7 +86,6 @@ export class DownloadDialogActor { sampling: tomogram.voxel_spacing, processing: tomogram.processing, }, - multipleTomograms, }) } @@ -100,13 +94,11 @@ export class DownloadDialogActor { baseUrl, step, tab, - multipleTomograms, }: { client: ApolloClient baseUrl: string step?: DownloadStep tab?: DownloadTab - multipleTomograms?: boolean }) { const { data } = await fetchTestSingleRun(client) const annotationFile = data.annotation_files[0] @@ -128,7 +120,6 @@ export class DownloadDialogActor { sampling: tomogram.voxel_spacing, processing: tomogram.processing, }, - multipleTomograms, }) } // #endregion Navigate @@ -219,7 +210,6 @@ export class DownloadDialogActor { tab, tomogram, step, - multipleTomograms = false, }: { baseUrl: string config?: string @@ -228,7 +218,6 @@ export class DownloadDialogActor { annotationFile?: { annotation: { id: string }; shape_type: string } tomogram?: { id: number; sampling: number; processing: string } step?: DownloadStep - multipleTomograms?: boolean }) { const expectedUrl = constructDialogUrl(baseUrl, { config, @@ -236,7 +225,6 @@ export class DownloadDialogActor { tab, tomogram, step, - multipleTomograms, }) const actualUrl = new URL(this.downloadDialogPage.url()) expect(actualUrl.pathname).toBe(expectedUrl.pathname) @@ -250,7 +238,6 @@ export class DownloadDialogActor { fileFormat, tab, step, - multipleTomograms = false, }: { baseUrl: string client: ApolloClient @@ -258,7 +245,6 @@ export class DownloadDialogActor { fileFormat?: string tab?: DownloadTab step?: DownloadStep - multipleTomograms?: boolean }) { const { data } = await fetchTestSingleRun(client) const tomogram = data.tomograms[0] @@ -274,7 +260,6 @@ export class DownloadDialogActor { processing: tomogram.processing, }, step, - multipleTomograms, }) } @@ -285,7 +270,6 @@ export class DownloadDialogActor { fileFormat, tab, step, - multipleTomograms = false, }: { baseUrl: string client: ApolloClient @@ -293,7 +277,6 @@ export class DownloadDialogActor { fileFormat?: string tab?: DownloadTab step?: DownloadStep - multipleTomograms?: boolean }) { const { data } = await fetchTestSingleRun(client) const annotationFile = data.annotation_files[0] @@ -316,7 +299,6 @@ export class DownloadDialogActor { processing: tomogram.processing, }, step, - multipleTomograms, }) } diff --git a/frontend/packages/data-portal/e2e/pageObjects/downloadDialog/utils.ts b/frontend/packages/data-portal/e2e/pageObjects/downloadDialog/utils.ts index 2751ab432..8167ceeda 100644 --- a/frontend/packages/data-portal/e2e/pageObjects/downloadDialog/utils.ts +++ b/frontend/packages/data-portal/e2e/pageObjects/downloadDialog/utils.ts @@ -31,7 +31,6 @@ export function constructDialogUrl( annotationFile, tomogram, fileFormat, - multipleTomograms = false, }: { tab?: string step?: string @@ -39,7 +38,6 @@ export function constructDialogUrl( annotationFile?: { annotation: { id: string }; shape_type: string } tomogram?: { id: number; sampling: number; processing: string } fileFormat?: string - multipleTomograms?: boolean }, ): URL { const expectedUrl = new URL(url) @@ -54,21 +52,14 @@ export function constructDialogUrl( } if (annotationFile) { - if (multipleTomograms) { - params.append(QueryParams.ReferenceTomogramId, String(tomogram!.id)) - } + params.append(QueryParams.ReferenceTomogramId, String(tomogram!.id)) params.append( QueryParams.AnnotationId, String(annotationFile.annotation.id), ) params.append(QueryParams.ObjectShapeType, annotationFile.shape_type) } else if (tomogram) { - if (multipleTomograms) { - params.append(QueryParams.DownloadTomogramId, String(tomogram.id)) - } else { - params.append(QueryParams.TomogramSampling, String(tomogram.sampling)) - params.append(QueryParams.TomogramProcessing, tomogram.processing) - } + params.append(QueryParams.DownloadTomogramId, String(tomogram.id)) } if (fileFormat) { @@ -79,11 +70,6 @@ export function constructDialogUrl( params.append(QueryParams.DownloadTab, tab) } - params.append( - multipleTomograms ? 'enable-feature' : 'disable-feature', - 'multipleTomograms', - ) - return expectedUrl } diff --git a/frontend/packages/data-portal/e2e/pageObjects/metadataDrawer/utils.ts b/frontend/packages/data-portal/e2e/pageObjects/metadataDrawer/utils.ts index 5953e8282..131c16357 100644 --- a/frontend/packages/data-portal/e2e/pageObjects/metadataDrawer/utils.ts +++ b/frontend/packages/data-portal/e2e/pageObjects/metadataDrawer/utils.ts @@ -19,7 +19,6 @@ import { getDatasetById } from 'app/graphql/getDatasetById.server' import { getRunById } from 'app/graphql/getRunById.server' import { getRunByIdV2 } from 'app/graphql/getRunByIdV2.server' import { ObjectShapeType } from 'app/types/shapeTypes' -import { isFiducial } from 'app/utils/tomograms' import { DrawerTestData, DrawerTestMetadata } from './types' @@ -102,37 +101,19 @@ function getTiltSeriesTestMetadata({ function getTomogramAccordionTestMetadata( response: GetRunByIdQuery, - multipleTomogramsEnabled: boolean, ): DrawerTestMetadata { - const tomogram = response.runs[0].tomogram_voxel_spacings[0].tomograms[0] - - return multipleTomogramsEnabled - ? { - totalTomograms: - response.tomograms_aggregate.aggregate!.count.toString(), - resolutionsAvailable: response.tomograms_for_resolutions.map((tomo) => - tomo.voxel_spacing.toString(), - ), - tomogramProcessing: - response.tomograms_for_distinct_processing_methods.map((tomo) => - startCase(tomo.processing), - ), - annotatedObjects: response.annotations_for_object_names - .map((annotation) => annotation.object_name) - .slice(0, 4), - } - : { - reconstructionSoftware: tomogram.reconstruction_software, - reconstructionMethod: tomogram.reconstruction_method, - processingSoftware: tomogram.processing_software, - availableProcessing: tomogram.processing, - smallestAvailableVoxelSpacing: tomogram.voxel_spacing, - size: `${tomogram.size_x}, ${tomogram.size_y}, ${tomogram.size_z}`, - fiducialAlignmentStatus: getBoolString( - isFiducial(tomogram.fiducial_alignment_status), - ), - ctfCorrected: tomogram.ctf_corrected ? 'Yes' : 'No', - } + return { + totalTomograms: response.tomograms_aggregate.aggregate!.count.toString(), + resolutionsAvailable: response.tomograms_for_resolutions.map((tomo) => + tomo.voxel_spacing.toString(), + ), + tomogramProcessing: response.tomograms_for_distinct_processing_methods.map( + (tomo) => startCase(tomo.processing), + ), + annotatedObjects: response.annotations_for_object_names + .map((annotation) => annotation.object_name) + .slice(0, 4), + } } function getAnnotationTestMetdata( @@ -250,7 +231,6 @@ export async function getSingleDatasetTestMetadata( // #region Data Getters export async function getSingleRunTestMetadata( client: ApolloClient, - multipleTomogramsEnabled: boolean, ): Promise { const { data } = await getRunById({ client, @@ -274,7 +254,7 @@ export async function getSingleRunTestMetadata( type: 'run', }), - ...getTomogramAccordionTestMetadata(data, multipleTomogramsEnabled), + ...getTomogramAccordionTestMetadata(data), }, } } From b6813db059a81d14fe16127e923e071f5eb4ab70 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 19:00:55 +0000 Subject: [PATCH 22/35] chore(main): release web 1.39.0 (#1437) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- frontend/CHANGELOG.md | 12 ++++++++++++ frontend/package.json | 2 +- release-please.manifest.json | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index d63909a34..dca2528e3 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [1.39.0](https://github.com/chanzuckerberg/cryoet-data-portal/compare/web-v1.38.0...web-v1.39.0) (2025-01-03) + + +### ✨ Features + +* Use V2 aggregate data in run page ([#1429](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1429)) ([f7754e4](https://github.com/chanzuckerberg/cryoet-data-portal/commit/f7754e4d88e20232f4456e61b51205727b90c1f8)) + + +### 🧹 Miscellaneous Chores + +* Remove Multiple Tomograms flag ([#1434](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1434)) ([531ece1](https://github.com/chanzuckerberg/cryoet-data-portal/commit/531ece1e955f936893e72a3184d7da3d723c4ecf)) + ## [1.38.0](https://github.com/chanzuckerberg/cryoet-data-portal/compare/web-v1.37.2...web-v1.38.0) (2025-01-02) diff --git a/frontend/package.json b/frontend/package.json index b5c530ed3..ea38019a2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "1.38.0", + "version": "1.39.0", "scripts": { "preinstall": "npx only-allow pnpm", "build": "pnpm -r build", diff --git a/release-please.manifest.json b/release-please.manifest.json index 6aea47e60..432e113ad 100644 --- a/release-please.manifest.json +++ b/release-please.manifest.json @@ -1,4 +1,4 @@ { - "frontend": "1.38.0", + "frontend": "1.39.0", "client/python/cryoet_data_portal": "4.3.0" } From 1acbf3074de170ea8891fd6bb07b5cbba64b45e0 Mon Sep 17 00:00:00 2001 From: Jeremy Asuncion Date: Fri, 3 Jan 2025 13:26:20 -0800 Subject: [PATCH 23/35] test: filter components unit tests (#1436) * BooleanFilter tests * DropdownFilterButton tests * InputFilter tests * MultiInputFilter tests * add key to DropdownFilterButton * RegexFilter tests * SelectFilter tests * TiltRangeFilter tests * increase jest timeout to 10s --- .../components/Filters/BooleanFilter.test.tsx | 53 ++++++ .../Filters/DropdownFilterButton.test.tsx | 111 +++++++++++ .../Filters/DropdownFilterButton.tsx | 40 ++-- .../components/Filters/InputFilter.test.tsx | 59 ++++++ .../app/components/Filters/InputFilter.tsx | 20 +- .../Filters/MultiInputFilter.test.tsx | 173 ++++++++++++++++++ .../components/Filters/MultiInputFilter.tsx | 22 ++- .../components/Filters/RegexFilter.test.tsx | 152 +++++++++++++++ .../app/components/Filters/RegexFilter.tsx | 20 +- .../components/Filters/SelectFilter.test.tsx | 131 +++++++++++++ .../app/components/Filters/SelectFilter.tsx | 39 ++-- .../Filters/TiltRangeFilter.test.tsx | 82 +++++++++ frontend/packages/data-portal/jest.config.cjs | 1 + 13 files changed, 843 insertions(+), 60 deletions(-) create mode 100644 frontend/packages/data-portal/app/components/Filters/BooleanFilter.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Filters/DropdownFilterButton.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Filters/InputFilter.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Filters/MultiInputFilter.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Filters/RegexFilter.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Filters/SelectFilter.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Filters/TiltRangeFilter.test.tsx diff --git a/frontend/packages/data-portal/app/components/Filters/BooleanFilter.test.tsx b/frontend/packages/data-portal/app/components/Filters/BooleanFilter.test.tsx new file mode 100644 index 000000000..2f651c51d --- /dev/null +++ b/frontend/packages/data-portal/app/components/Filters/BooleanFilter.test.tsx @@ -0,0 +1,53 @@ +import { jest } from '@jest/globals' +// eslint-disable-next-line testing-library/no-manual-cleanup +import { cleanup, render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { BooleanFilter } from './BooleanFilter' + +describe('', () => { + it('should render label', () => { + const label = 'test' + render( {}} value={false} />) + + expect(screen.getByText(label)).toBeVisible() + }) + + it('should render caption', () => { + const caption = 'test' + + render( {}} value={false} />) + expect(screen.queryByText(caption)).not.toBeInTheDocument() + cleanup() + + render( + {}} + value={false} + />, + ) + expect(screen.getByText(caption)).toBeVisible() + }) + + it('should render initial value', () => { + render( {}} value />) + expect(screen.getByRole('checkbox')).toBeChecked() + }) + + it('should update value', async () => { + const onChange = jest.fn() + + for (const value of [true, false]) { + render() + expect(onChange).not.toHaveBeenCalled() + + // eslint-disable-next-line no-await-in-loop + await userEvent.click(screen.getByRole('checkbox')) + expect(onChange).toHaveBeenCalledWith(!value) + cleanup() + onChange.mockClear() + } + }) +}) diff --git a/frontend/packages/data-portal/app/components/Filters/DropdownFilterButton.test.tsx b/frontend/packages/data-portal/app/components/Filters/DropdownFilterButton.test.tsx new file mode 100644 index 000000000..be084b58d --- /dev/null +++ b/frontend/packages/data-portal/app/components/Filters/DropdownFilterButton.test.tsx @@ -0,0 +1,111 @@ +import { jest } from '@jest/globals' +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { DropdownFilterButtonProps } from './DropdownFilterButton' + +async function renderDropdownFilterButton({ + activeFilters = [], + children = null, + disabled, + label = '', + onApply = jest.fn(), + onCancel = jest.fn(), + onOpen = jest.fn(), + onRemoveFilter = jest.fn(), +}: Partial = {}) { + const { DropdownFilterButton } = await import('./DropdownFilterButton') + + render( + + {children} + , + ) +} + +describe('', () => { + it('should render label', async () => { + const label = 'Test Label' + await renderDropdownFilterButton({ label }) + + expect(screen.getByText(label)).toBeVisible() + }) + + it('should render active filter chips', async () => { + const filterWithoutLabel = { value: 'test1' } + const filterWithLabel = { label: 'Test Filter', value: 'test2' } + const activeFilters = [filterWithoutLabel, filterWithLabel] + + await renderDropdownFilterButton({ activeFilters }) + + expect(screen.getByText(filterWithoutLabel.value)).toBeVisible() + expect(screen.getByText(filterWithLabel.label)).toBeVisible() + expect(screen.getByText(filterWithLabel.value)).toBeVisible() + }) + + it('should remove active filter on click', async () => { + const filter = { label: 'Test Filter', value: 'test' } + const onRemoveFilter = jest.fn() + await renderDropdownFilterButton({ + onRemoveFilter, + activeFilters: [filter], + }) + + await userEvent.click(screen.getByRole('button', { name: 'remove-filter' })) + expect(onRemoveFilter).toHaveBeenCalledWith(filter) + }) + + it('should open popup on click', async () => { + const label = 'Test Label' + const children = 'Test Children' + const onOpen = jest.fn() + await renderDropdownFilterButton({ children, label, onOpen }) + expect(screen.queryByText(children)).not.toBeInTheDocument() + expect(onOpen).not.toHaveBeenCalled() + + await userEvent.click(screen.getByRole('button', { name: label })) + expect(screen.getByText(children)).toBeVisible() + expect(onOpen).toHaveBeenCalled() + }) + + it('should apply filters on click', async () => { + const onApply = jest.fn() + const label = 'Test Label' + const children = 'Test children' + await renderDropdownFilterButton({ children, label, onApply }) + + await userEvent.click(screen.getByRole('button', { name: label })) + await userEvent.click(screen.getByRole('button', { name: 'apply' })) + expect(onApply).toHaveBeenCalled() + expect(screen.queryByText(children)).not.toBeInTheDocument() + }) + + it('should cancel on click', async () => { + const onCancel = jest.fn() + const label = 'Test Label' + const children = 'Test Children' + await renderDropdownFilterButton({ children, onCancel, label }) + + await userEvent.click(screen.getByRole('button', { name: label })) + await userEvent.click(screen.getByRole('button', { name: 'cancel' })) + expect(onCancel).toHaveBeenCalled() + expect(screen.queryByText(children)).not.toBeInTheDocument() + }) + + it('should disable apply button', async () => { + const onApply = jest.fn() + const label = 'Test Label' + await renderDropdownFilterButton({ label, onApply, disabled: true }) + + await userEvent.click(screen.getByRole('button', { name: label })) + expect(screen.getByRole('button', { name: 'apply' })).toBeDisabled() + }) +}) diff --git a/frontend/packages/data-portal/app/components/Filters/DropdownFilterButton.tsx b/frontend/packages/data-portal/app/components/Filters/DropdownFilterButton.tsx index d95d3cdfb..f7edd026b 100644 --- a/frontend/packages/data-portal/app/components/Filters/DropdownFilterButton.tsx +++ b/frontend/packages/data-portal/app/components/Filters/DropdownFilterButton.tsx @@ -1,9 +1,10 @@ import { Button, Icon } from '@czi-sds/components' -import Popover from '@mui/material/Popover' +// eslint-disable-next-line cryoet-data-portal/no-root-mui-import +import { Popover } from '@mui/material' import { ReactNode, useRef, useState } from 'react' import { QueryParams } from 'app/constants/query' -import { i18n } from 'app/i18n' +import { useI18n } from 'app/hooks/useI18n' import { cns } from 'app/utils/cns' import { getPrefixedId } from 'app/utils/idPrefixes' @@ -13,6 +14,18 @@ export interface ActiveDropdownFilterData { value: string } +export interface DropdownFilterButtonProps { + activeFilters: ActiveDropdownFilterData[] + children: ReactNode + description?: ReactNode + disabled?: boolean + label: string + onApply(): void + onCancel(): void + onOpen?(): void + onRemoveFilter(filter: ActiveDropdownFilterData): void +} + export function DropdownFilterButton({ activeFilters, children, @@ -23,19 +36,10 @@ export function DropdownFilterButton({ onCancel, onOpen, onRemoveFilter, -}: { - activeFilters: ActiveDropdownFilterData[] - children: ReactNode - description?: ReactNode - disabled?: boolean - label: string - onApply(): void - onCancel(): void - onOpen?(): void - onRemoveFilter(filter: ActiveDropdownFilterData): void -}) { +}: DropdownFilterButtonProps) { const [open, setOpen] = useState(false) const buttonRef = useRef(null) + const { t } = useI18n() return (
@@ -76,7 +80,10 @@ export function DropdownFilterButton({
{activeFilters.map((filter) => { return ( -
+
{filter.label && (

{filter.label} @@ -92,6 +99,7 @@ export function DropdownFilterButton({

diff --git a/frontend/packages/data-portal/app/components/Filters/InputFilter.test.tsx b/frontend/packages/data-portal/app/components/Filters/InputFilter.test.tsx new file mode 100644 index 000000000..7a4eba2bc --- /dev/null +++ b/frontend/packages/data-portal/app/components/Filters/InputFilter.test.tsx @@ -0,0 +1,59 @@ +import { jest } from '@jest/globals' +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { InputFilter, InputFilterProps } from './InputFilter' + +function renderInputFilter({ + id = 'id', + label = 'label', + onChange = jest.fn(), + value = '', + hideLabel, +}: Partial = {}) { + render( + , + ) +} + +describe('', () => { + it('should render label', () => { + const label = 'Test Label' + renderInputFilter({ label }) + + expect(screen.getByText(label)).toBeVisible() + }) + + it('should hide label', () => { + const label = 'Test Label' + renderInputFilter({ label, hideLabel: true }) + + expect(screen.queryByText(label)).not.toBeInTheDocument() + }) + + it('should update value', async () => { + const onChange = jest.fn() + renderInputFilter({ onChange }) + + const input = screen.getByRole('textbox') + const value = 'test' + await userEvent.type(input, value) + + for (let i = 0; i < value.length; i += 1) { + expect(onChange.mock.calls[i][0]).toBe(value[i]) + } + }) + + it('should render with initial value', () => { + const value = 'Test Value' + renderInputFilter({ value }) + + expect(screen.getByRole('textbox')).toHaveValue(value) + }) +}) diff --git a/frontend/packages/data-portal/app/components/Filters/InputFilter.tsx b/frontend/packages/data-portal/app/components/Filters/InputFilter.tsx index 4b0dba99a..20ea40594 100644 --- a/frontend/packages/data-portal/app/components/Filters/InputFilter.tsx +++ b/frontend/packages/data-portal/app/components/Filters/InputFilter.tsx @@ -2,6 +2,16 @@ import { InputText } from '@czi-sds/components' import styles from './Filters.module.css' +export interface InputFilterProps { + id: string + label: string + value: string + onChange(value: string): void + hideLabel?: boolean + className?: string + error?: boolean +} + export function InputFilter({ id, label, @@ -10,15 +20,7 @@ export function InputFilter({ hideLabel, className, error, -}: { - id: string - label: string - onChange(value: string): void - value: string - hideLabel?: boolean - className?: string - error?: boolean -}) { +}: InputFilterProps) { return ( // apply style override here since it has higher specificity and MUI is weird
diff --git a/frontend/packages/data-portal/app/components/Filters/MultiInputFilter.test.tsx b/frontend/packages/data-portal/app/components/Filters/MultiInputFilter.test.tsx new file mode 100644 index 000000000..23f21dea8 --- /dev/null +++ b/frontend/packages/data-portal/app/components/Filters/MultiInputFilter.test.tsx @@ -0,0 +1,173 @@ +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { QueryParams } from 'app/constants/query' +import { RemixMock } from 'app/mocks/Remix.mock' + +import { InputFilterData, MultiInputFilterProps } from './MultiInputFilter' + +const remixMock = new RemixMock() + +async function renderMultiInputFilter({ + filters = [], + label = '', + subtitle, + title, +}: Partial = {}) { + const { MultiInputFilter } = await import('./MultiInputFilter') + + render( + , + ) +} + +describe('', () => { + beforeEach(() => { + remixMock.reset() + }) + + it('should render label', async () => { + const label = 'Test Label' + await renderMultiInputFilter({ label }) + + expect(screen.getByText(label)).toBeInTheDocument() + }) + + it('should render default title and subtitle', async () => { + await renderMultiInputFilter() + await userEvent.click(screen.getByRole('button')) + + expect(screen.getByText('filterByAnyOfTheFollowing')).toBeInTheDocument() + expect(screen.getByText('(limitOneValuePerField)')).toBeInTheDocument() + }) + + it('should render title', async () => { + const title = 'Test Title' + await renderMultiInputFilter({ title }) + await userEvent.click(screen.getByRole('button')) + + expect(screen.getByText(title)).toBeInTheDocument() + }) + + it('should render subtitle', async () => { + const subtitle = 'Test Subtitle' + await renderMultiInputFilter({ subtitle }) + await userEvent.click(screen.getByRole('button')) + + expect(screen.getByText(subtitle)).toBeInTheDocument() + }) + + it('should update values', async () => { + const filter: InputFilterData = { + id: 'filter', + label: 'Filter', + queryParam: QueryParams.DatasetId, + } + + await renderMultiInputFilter({ filters: [filter] }) + await userEvent.click(screen.getByRole('button')) + + const input = screen.getByRole('textbox') + const value = 'value' + await userEvent.type(input, value) + expect(input).toHaveValue(value) + }) + + it('should apply filters on click', async () => { + const filter: InputFilterData = { + id: 'filter', + label: 'Filter', + queryParam: QueryParams.DatasetId, + } + + await renderMultiInputFilter({ filters: [filter] }) + await userEvent.click(screen.getByRole('button')) + + const input = screen.getByRole('textbox') + const value = '123' + await userEvent.type(input, value) + await userEvent.click(screen.getByRole('button', { name: 'apply' })) + + expect(remixMock.getLastSetParams()?.toString()).toEqual( + `${QueryParams.DatasetId}=${value}`, + ) + }) + + it('should reset filters on click', async () => { + const filter: InputFilterData = { + id: 'filter', + label: 'Filter', + queryParam: QueryParams.DatasetId, + } + + await renderMultiInputFilter({ filters: [filter] }) + await userEvent.click(screen.getByRole('button')) + + const input = screen.getByRole('textbox') + const value = '123' + await userEvent.type(input, value) + await userEvent.click(screen.getByRole('button', { name: 'cancel' })) + + expect(remixMock.setParams).not.toHaveBeenCalled() + }) + + it('should show initial values', async () => { + const label = 'Open Filters' + const filter: InputFilterData = { + id: 'filter', + label: 'Filter', + queryParam: QueryParams.DatasetId, + } + + remixMock.mockSearchParams( + new URLSearchParams([[filter.queryParam, '123']]), + ) + + await renderMultiInputFilter({ label, filters: [filter] }) + await userEvent.click(screen.getByRole('button', { name: label })) + + const input = screen.getByRole('textbox') + const value = '123' + expect(input).toHaveValue(value) + }) + + it("should disable apply if values haven't changed", async () => { + const label = 'Open Filters' + const filter: InputFilterData = { + id: 'filter', + label: 'Filter', + queryParam: QueryParams.DatasetId, + } + + remixMock.mockSearchParams( + new URLSearchParams([[filter.queryParam, '123']]), + ) + + await renderMultiInputFilter({ label, filters: [filter] }) + await userEvent.click(screen.getByRole('button', { name: label })) + + expect(screen.getByRole('button', { name: 'apply' })).toBeDisabled() + }) + + it('should disable apply if invalid prefix id', async () => { + const filter: InputFilterData = { + id: 'filter', + label: 'Filter', + queryParam: QueryParams.DatasetId, + } + + await renderMultiInputFilter({ filters: [filter] }) + await userEvent.click(screen.getByRole('button')) + + const input = screen.getByRole('textbox') + const value = 'derp-123' + await userEvent.type(input, value) + + expect(screen.getByRole('button', { name: 'apply' })).toBeDisabled() + }) +}) diff --git a/frontend/packages/data-portal/app/components/Filters/MultiInputFilter.tsx b/frontend/packages/data-portal/app/components/Filters/MultiInputFilter.tsx index 58383a4a0..2f4c404ac 100644 --- a/frontend/packages/data-portal/app/components/Filters/MultiInputFilter.tsx +++ b/frontend/packages/data-portal/app/components/Filters/MultiInputFilter.tsx @@ -3,7 +3,7 @@ import { isEqual } from 'lodash-es' import { useCallback, useMemo, useState } from 'react' import { QueryParams } from 'app/constants/query' -import { i18n } from 'app/i18n' +import { useI18n } from 'app/hooks/useI18n' import { cns } from 'app/utils/cns' import { isFilterPrefixValid, removeIdPrefix } from 'app/utils/idPrefixes' @@ -17,17 +17,19 @@ export interface InputFilterData { hideLabel?: boolean } +export interface MultiInputFilterProps { + filters: InputFilterData[] + label: string + title?: string + subtitle?: string +} + export function MultiInputFilter({ filters, label, title, subtitle, -}: { - filters: InputFilterData[] - label: string - title?: string - subtitle?: string -}) { +}: MultiInputFilterProps) { const [searchParams, setSearchParams] = useSearchParams() const getQueryParamValues = useCallback( @@ -51,6 +53,8 @@ export function MultiInputFilter({ return hasInvalidPrefix || isEqual(values, getQueryParamValues()) }, [filters, getQueryParamValues, values]) + const { t } = useI18n() + return (

- {title ?? i18n.filterByAnyOfTheFollowing} + {title ?? t('filterByAnyOfTheFollowing')}

- {subtitle ?? `(${i18n.limitOneValuePerField})`} + {subtitle ?? `(${t('limitOneValuePerField')})`}

} diff --git a/frontend/packages/data-portal/app/components/Filters/RegexFilter.test.tsx b/frontend/packages/data-portal/app/components/Filters/RegexFilter.test.tsx new file mode 100644 index 000000000..6cf564f9b --- /dev/null +++ b/frontend/packages/data-portal/app/components/Filters/RegexFilter.test.tsx @@ -0,0 +1,152 @@ +import { beforeEach } from '@jest/globals' +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { IdPrefix } from 'app/constants/idPrefixes' +import { QueryParams } from 'app/constants/query' +import { RemixMock } from 'app/mocks/Remix.mock' + +import { RegexFilterProps } from './RegexFilter' + +async function renderRegexFilter({ + displayNormalizer, + id = 'id', + label = 'label', + paramNormalizer, + queryParam = QueryParams.DatasetId, + regex = /.*/, + title = 'title', +}: Partial = {}) { + const { RegexFilter } = await import('./RegexFilter') + + render( + , + ) +} + +const remixMock = new RemixMock() + +describe('', () => { + beforeEach(() => { + remixMock.reset() + }) + + it('should render title', async () => { + const title = 'Test Title' + await renderRegexFilter({ title }) + await userEvent.click(screen.getByRole('button')) + + expect(screen.getByText(title)).toBeVisible() + }) + + it('should render initial value', async () => { + const label = 'Open Filters' + const queryParam = QueryParams.DatasetId + const value = '123' + remixMock.mockSearchParams(new URLSearchParams([[queryParam, value]])) + await renderRegexFilter({ + label, + queryParam, + }) + + expect(screen.getByText(`${IdPrefix.Dataset}-${value}`)).toBeVisible() + + await userEvent.click(screen.getByRole('button', { name: label })) + expect(screen.getByRole('textbox')).toHaveValue(value) + }) + + it('should disable apply if value does not match regex', async () => { + const label = 'Open Filters' + const queryParam = QueryParams.DatasetId + await renderRegexFilter({ + label, + queryParam, + regex: /[a-z]+/, + }) + + await userEvent.click(screen.getByRole('button', { name: label })) + await userEvent.type(screen.getByRole('textbox'), '123') + + expect(screen.getByRole('button', { name: 'apply' })).toBeDisabled() + }) + + it('should set value on apply click', async () => { + const label = 'Open Filters' + const queryParam = QueryParams.DatasetId + await renderRegexFilter({ + label, + queryParam, + }) + + await userEvent.click(screen.getByRole('button', { name: label })) + await userEvent.type(screen.getByRole('textbox'), '123') + await userEvent.click(screen.getByRole('button', { name: 'apply' })) + + expect(remixMock.getLastSetParams()?.toString()).toBe(`${queryParam}=123`) + }) + + it('should normalize initial value', async () => { + const label = 'Open Filters' + const queryParam = QueryParams.DatasetId + const value = '123' + const normalizedValue = `${IdPrefix.Dataset}-123` + remixMock.mockSearchParams(new URLSearchParams([[queryParam, value]])) + await renderRegexFilter({ + label, + queryParam, + displayNormalizer: () => normalizedValue, + }) + + expect(screen.getByText(normalizedValue)).toBeVisible() + + await userEvent.click(screen.getByRole('button', { name: label })) + expect(screen.getByRole('textbox')).toHaveValue(value) + }) + + it('should normalize value', async () => { + const label = 'Open Filters' + const queryParam = QueryParams.DatasetId + const value = '123' + const normalizedValue = `${IdPrefix.Dataset}-123` + await renderRegexFilter({ + label, + queryParam, + displayNormalizer: () => normalizedValue, + }) + + await userEvent.click(screen.getByRole('button', { name: label })) + await userEvent.type(screen.getByRole('textbox'), value) + await userEvent.click(screen.getByRole('button', { name: 'apply' })) + await userEvent.click(screen.getByRole('button', { name: label })) + + expect(screen.getByRole('textbox')).toHaveValue(normalizedValue) + }) + + it('should normalize param value', async () => { + const label = 'Open Filters' + const queryParam = QueryParams.DatasetId + const value = `${IdPrefix.Dataset}-123` + const normalizedValue = `123` + await renderRegexFilter({ + label, + queryParam, + paramNormalizer: () => normalizedValue, + }) + + await userEvent.click(screen.getByRole('button', { name: label })) + await userEvent.type(screen.getByRole('textbox'), value) + await userEvent.click(screen.getByRole('button', { name: 'apply' })) + + expect(remixMock.getLastSetParams()?.toString()).toBe( + `${queryParam}=${normalizedValue}`, + ) + }) +}) diff --git a/frontend/packages/data-portal/app/components/Filters/RegexFilter.tsx b/frontend/packages/data-portal/app/components/Filters/RegexFilter.tsx index 345304309..095bb7f28 100644 --- a/frontend/packages/data-portal/app/components/Filters/RegexFilter.tsx +++ b/frontend/packages/data-portal/app/components/Filters/RegexFilter.tsx @@ -7,6 +7,16 @@ import { useI18n } from 'app/hooks/useI18n' import { DropdownFilterButton } from './DropdownFilterButton' import { InputFilter } from './InputFilter' +export interface RegexFilterProps { + id: string + label: string + title: string + queryParam: QueryParams + regex: RegExp + displayNormalizer?(value: string): string + paramNormalizer?(value: string): string +} + // TODO: make this more generic as a single input popup filter export function RegexFilter({ id, @@ -16,15 +26,7 @@ export function RegexFilter({ regex: validationRegex, displayNormalizer, paramNormalizer, -}: { - id: string - label: string - title: string - queryParam: QueryParams - regex: RegExp - displayNormalizer?: (value: string) => string - paramNormalizer?: (value: string) => string -}) { +}: RegexFilterProps) { const { t } = useI18n() const [searchParams, setSearchParams] = useSearchParams() diff --git a/frontend/packages/data-portal/app/components/Filters/SelectFilter.test.tsx b/frontend/packages/data-portal/app/components/Filters/SelectFilter.test.tsx new file mode 100644 index 000000000..1246f96d0 --- /dev/null +++ b/frontend/packages/data-portal/app/components/Filters/SelectFilter.test.tsx @@ -0,0 +1,131 @@ +import { jest } from '@jest/globals' +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { BaseFilterOption } from 'app/types/filter' + +import { SelectFilter, SelectFilterProps } from './SelectFilter' + +function renderSelectFilter< + Option extends BaseFilterOption, + Multiple extends boolean = false, +>({ + details, + label = '', + multiple, + onChange = jest.fn(), + options = [], + search, + title, + value, +}: Partial> = {}) { + render( + , + ) +} + +describe('', () => { + it('should render label', () => { + const label = 'Test Label' + renderSelectFilter({ label }) + + expect(screen.getByText(label)).toBeVisible() + }) + + it('should render title', async () => { + const title = 'Test Title' + renderSelectFilter({ title }) + await userEvent.click(screen.getByRole('button')) + + expect(screen.getByText(title)).toBeVisible() + }) + + it('should render details', () => { + const details = 'Test Details' + renderSelectFilter({ details }) + + expect(screen.getByText(details)).toBeVisible() + }) + + it('should render with initial value', () => { + const value = 'Test Value' + renderSelectFilter({ + value: { value }, + }) + + expect(screen.getByText(value)).toBeVisible() + }) + + it('should render options', async () => { + const options = [ + { value: 'Option 1' }, + { value: 'Option 2' }, + { value: 'Option 3' }, + ] + renderSelectFilter({ options }) + await userEvent.click(screen.getByRole('button')) + + options.forEach(({ value }) => { + expect(screen.getByText(value)).toBeVisible() + }) + }) + + it('should update value', async () => { + const options = [ + { value: 'Option 1' }, + { value: 'Option 2' }, + { value: 'Option 3' }, + ] + const { value } = options[1] + renderSelectFilter({ options }) + + await userEvent.click(screen.getByRole('button')) + await userEvent.click(screen.getByText(value)) + + expect(screen.getByText(value)).toBeVisible() + }) + + it('should select multiple values', async () => { + const options = [ + { value: 'Option 1' }, + { value: 'Option 2' }, + { value: 'Option 3' }, + ] + const value1 = options[0].value + const value2 = options[1].value + renderSelectFilter({ options, multiple: true }) + + await userEvent.click(screen.getByRole('button')) + await userEvent.click(screen.getByText(value1)) + await userEvent.click(screen.getByText(value2)) + await userEvent.keyboard('{Escape}') + + expect(screen.getByText(value1)).toBeVisible() + expect(screen.getByText(value2)).toBeVisible() + }) + + it('should search values', async () => { + const options = [ + { value: 'Option 1' }, + { value: 'Option 2' }, + { value: 'Option 3' }, + ] + renderSelectFilter({ options, search: true }) + + await userEvent.click(screen.getByRole('button')) + await userEvent.type(screen.getByRole('combobox'), '1') + + expect(screen.getByText(options[0].value)).toBeVisible() + expect(screen.queryByText(options[1].value)).not.toBeInTheDocument() + expect(screen.queryByText(options[2].value)).not.toBeInTheDocument() + }) +}) diff --git a/frontend/packages/data-portal/app/components/Filters/SelectFilter.tsx b/frontend/packages/data-portal/app/components/Filters/SelectFilter.tsx index 155d72a52..c11d198b4 100644 --- a/frontend/packages/data-portal/app/components/Filters/SelectFilter.tsx +++ b/frontend/packages/data-portal/app/components/Filters/SelectFilter.tsx @@ -12,6 +12,27 @@ import styles from './Filters.module.css' type DisableClearable = false type FreeSolo = false +export interface SelectFilterProps< + Option extends BaseFilterOption, + Multiple extends boolean = false, +> { + className?: string + details?: ReactNode + groupBy?: ( + option: AutocompleteValue, + ) => string + label: string + multiple?: Multiple + onChange( + value: AutocompleteValue, + ): void + options: Option[] + popperClassName?: string + search?: boolean + title?: string + value?: AutocompleteValue +} + /** * Wrapper over ComplexFilter to add a type parameter for the autocomplete * option so that we can add strict typing to the option keys. @@ -31,23 +52,7 @@ export function SelectFilter< search, title, value, -}: { - className?: string - details?: ReactNode - groupBy?: ( - option: AutocompleteValue, - ) => string - label: string - multiple?: Multiple - onChange( - value: AutocompleteValue, - ): void - options: Option[] - popperClassName?: string - search?: boolean - title?: string - value?: AutocompleteValue -}) { +}: SelectFilterProps) { const labelValueMap = useMemo( () => Object.fromEntries( diff --git a/frontend/packages/data-portal/app/components/Filters/TiltRangeFilter.test.tsx b/frontend/packages/data-portal/app/components/Filters/TiltRangeFilter.test.tsx new file mode 100644 index 000000000..68c285353 --- /dev/null +++ b/frontend/packages/data-portal/app/components/Filters/TiltRangeFilter.test.tsx @@ -0,0 +1,82 @@ +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { QueryParams } from 'app/constants/query' +import { RemixMock } from 'app/mocks/Remix.mock' + +const remixMock = new RemixMock() + +async function renderTiltRangeFilter() { + const { TiltRangeFilter } = await import('./TiltRangeFilter') + render() +} + +describe('', () => { + beforeEach(() => { + remixMock.reset() + }) + + it('should disable for invalid input', async () => { + await renderTiltRangeFilter() + await userEvent.click(screen.getByRole('button')) + + await userEvent.type(screen.getByLabelText('tilt-min-input'), '10') + await userEvent.type(screen.getByLabelText('tilt-max-input'), '5') + + expect(screen.getByRole('button', { name: 'apply' })).toBeDisabled() + }) + + it('should use initial values', async () => { + remixMock.mockSearchParams( + new URLSearchParams([ + [QueryParams.TiltRangeMin, '5'], + [QueryParams.TiltRangeMax, '10'], + ]), + ) + await renderTiltRangeFilter() + await userEvent.click(screen.getByRole('button', { name: 'tiltRange' })) + + expect(screen.getByLabelText('tilt-min-input')).toHaveValue(5) + expect(screen.getByLabelText('tilt-max-input')).toHaveValue(10) + }) + + it('should apply on click', async () => { + await renderTiltRangeFilter() + await userEvent.click(screen.getByRole('button')) + + await userEvent.type(screen.getByLabelText('tilt-min-input'), '5') + await userEvent.type(screen.getByLabelText('tilt-max-input'), '10') + await userEvent.click(screen.getByRole('button', { name: 'apply' })) + + expect(remixMock.getLastSetParams()?.toString()).toBe( + `${QueryParams.TiltRangeMin}=5&${QueryParams.TiltRangeMax}=10`, + ) + }) + + it('should reset on click', async () => { + await renderTiltRangeFilter() + await userEvent.click(screen.getByRole('button')) + + await userEvent.type(screen.getByLabelText('tilt-min-input'), '5') + await userEvent.type(screen.getByLabelText('tilt-max-input'), '10') + await userEvent.click(screen.getByRole('button', { name: 'cancel' })) + + expect(remixMock.setParams).not.toHaveBeenCalled() + await userEvent.click(screen.getByRole('button')) + expect(screen.getByLabelText('tilt-min-input')).toHaveValue(null) + expect(screen.getByLabelText('tilt-max-input')).toHaveValue(null) + }) + + it('should remove filter', async () => { + remixMock.mockSearchParams( + new URLSearchParams([ + [QueryParams.TiltRangeMin, '5'], + [QueryParams.TiltRangeMax, '10'], + ]), + ) + await renderTiltRangeFilter() + + await userEvent.click(screen.getByRole('button', { name: 'remove-filter' })) + expect(remixMock.getLastSetParams()?.toString()).toBe('') + }) +}) diff --git a/frontend/packages/data-portal/jest.config.cjs b/frontend/packages/data-portal/jest.config.cjs index a731aab92..09de0bc28 100644 --- a/frontend/packages/data-portal/jest.config.cjs +++ b/frontend/packages/data-portal/jest.config.cjs @@ -1,5 +1,6 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { + testTimeout: 10000, preset: 'ts-jest/presets/default-esm', setupFilesAfterEnv: ['@testing-library/jest-dom', '/setupTests.ts'], testEnvironment: 'jsdom', From d634ebd72d6f907b06586a58b6977f2f803a2b07 Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:37:01 -0800 Subject: [PATCH 24/35] feat: Migrate datasets page query (#1438) * other file * remove interoplation * finish * fix lint * rm ds store --- .gitignore | 1 + .../getDatasetsFilterValuesV2.server.ts | 64 ++++ .../app/graphql/getDatasetByIdV2.server.ts | 17 +- .../app/graphql/getDatasetsV2.server.ts | 355 ++++++++++++++++++ .../app/graphql/getRunByIdV2.server.ts | 4 +- .../data-portal/app/hooks/useDatasets.ts | 16 +- .../app/hooks/useDatasetsFilterData.ts | 30 +- .../app/routes/browse-data.datasets.tsx | 24 +- .../packages/eslint-config/typescript.cjs | 3 + 9 files changed, 468 insertions(+), 46 deletions(-) create mode 100644 frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts create mode 100644 frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts diff --git a/.gitignore b/.gitignore index b78e1fb63..063106363 100644 --- a/.gitignore +++ b/.gitignore @@ -137,6 +137,7 @@ dmypy.json .idea .terraform +.DS_Store # Files specific to this repo webdav_settings.json diff --git a/frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts b/frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts new file mode 100644 index 000000000..e1d02e4eb --- /dev/null +++ b/frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts @@ -0,0 +1,64 @@ +import { gql } from 'app/__generated_v2__' + +/** + * Shares filter options queries between datasets and deposition pages (filters are near identical). + * + * Parent query must define $depositionFilter. + */ +export const GET_DATASETS_FILTER_VALUES_FRAGMENT = gql(` + fragment DatasetsFilterValues on Query { + distinctOrganismNames: datasetsAggregate(where: { depositionId: $depositionFilter }) { + aggregate { + count + groupBy { + organismName + } + } + } + + distinctCameraManufacturers: tiltseriesAggregate(where: { depositionId: $depositionFilter }) { + aggregate { + count + groupBy { + cameraManufacturer + } + } + } + + distinctReconstructionMethods: tomogramsAggregate(where: { depositionId: $depositionFilter }) { + aggregate { + count + groupBy { + reconstructionMethod + } + } + } + + distinctReconstructionSoftwares: tomogramsAggregate(where: { depositionId: $depositionFilter }) { + aggregate { + count + groupBy { + reconstructionSoftware + } + } + } + + distinctObjectNames: annotationsAggregate(where: { depositionId: $depositionFilter }) { + aggregate { + count + groupBy { + objectName + } + } + } + + distinctShapeTypes: annotationShapesAggregate(where: { annotation: { depositionId: $depositionFilter } }) { + aggregate { + count + groupBy { + shapeType + } + } + } + } +`) diff --git a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts index 733b3c6a7..a4fec8cd8 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts @@ -218,6 +218,8 @@ function getRunFilter( datasetId: { _eq: datasetId, }, + tiltseries: {}, + annotations: {}, } // Deposition filter: @@ -231,13 +233,6 @@ function getRunFilter( // Tilt series filters: const tiltRangeMin = parseFloat(filterState.tiltSeries.min) const tiltRangeMax = parseFloat(filterState.tiltSeries.max) - if ( - Number.isFinite(tiltRangeMin) || - Number.isFinite(tiltRangeMax) || - filterState.tiltSeries.qualityScore.length > 0 - ) { - where.tiltseries = {} - } if (Number.isFinite(tiltRangeMin) || Number.isFinite(tiltRangeMax)) { where.tiltseries!.tiltRange = { _gte: Number.isFinite(tiltRangeMin) @@ -257,14 +252,6 @@ function getRunFilter( } // Annotation filters: - if ( - filterState.includedContents.isGroundTruthEnabled || - filterState.annotation.objectNames.length > 0 || - filterState.annotation.objectShapeTypes.length > 0 || - filterState.annotation.objectId !== null - ) { - where.annotations = {} - } if (filterState.includedContents.isGroundTruthEnabled) { where.annotations!.groundTruthStatus = { _eq: true } } diff --git a/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts new file mode 100644 index 000000000..60d2f33d1 --- /dev/null +++ b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts @@ -0,0 +1,355 @@ +import type { + ApolloClient, + ApolloQueryResult, + NormalizedCacheObject, +} from '@apollo/client' + +import { gql } from 'app/__generated_v2__' +import { + Annotation_File_Shape_Type_Enum, + DatasetWhereClause, + Fiducial_Alignment_Status_Enum, + GetDatasetsV2Query, + OrderBy, + Tomogram_Reconstruction_Method_Enum, +} from 'app/__generated_v2__/graphql' +import { MAX_PER_PAGE } from 'app/constants/pagination' +import { + DEFAULT_TILT_RANGE_MAX, + DEFAULT_TILT_RANGE_MIN, +} from 'app/constants/tiltSeries' +import { FilterState, getFilterState } from 'app/hooks/useFilter' + +const GET_DATASETS_QUERY = gql(` + query GetDatasetsV2( + $limit: Int, + $offset: Int, + $orderBy: [DatasetOrderByClause!]!, + $filter: DatasetWhereClause!, + $depositionFilter: IntComparators # Unused, but must be defined because DatasetsFilterValues references it. + ) { + datasets( + where: $filter + orderBy: $orderBy, + limitOffset: { + limit: $limit, + offset: $offset + } + ) { + id + title + organismName + datasetPublications + keyPhotoThumbnailUrl + relatedDatabaseEntries + authors(orderBy: { authorListOrder: asc }) { + edges { + node { + name + primaryAuthorStatus + correspondingAuthorStatus + } + } + } + runsCount: runsAggregate { + aggregate { + count + } + } + distinctObjectNames: runsAggregate { + aggregate { + count + groupBy { + annotations { + objectName + } + } + } + } + } + + totalDatasetsCount: datasetsAggregate { + aggregate { + count + } + } + filteredDatasetsCount: datasetsAggregate(where: $filter) { + aggregate { + count + } + } + + ...DatasetsFilterValues + } +`) + +function getFilter( + filterState: FilterState, + searchText?: string, +): DatasetWhereClause { + const where: DatasetWhereClause = { + runs: { annotations: {}, tiltseries: {}, tomograms: {} }, + } + + // Search by Dataset Name + if (searchText) { + where.title = { + _ilike: `%${searchText}%`, + } + } + + // INCLUDED CONTENTS SECTION + // Ground Truth Annotation + if (filterState.includedContents.isGroundTruthEnabled) { + where.runs!.annotations!.groundTruthStatus = { + _eq: true, + } + } + // Available Files + // TODO(bchu): Implement when available in API. + // filterState.includedContents.availableFiles.forEach((file) => + // match(file) + // .with('raw-frames', () => + // where.push({ + // runs: { + // tiltseries: { + // frames_count: { + // _gt: 0, + // }, + // }, + // }, + // }), + // ) + // .with('tilt-series', () => + // where.push({ + // runs: { + // tiltseries_aggregate: { + // count: { + // predicate: { + // _gt: 0, + // }, + // }, + // }, + // }, + // }), + // ) + // .with('tilt-series-alignment', () => + // where.push({ + // runs: { + // tiltseries: { + // https_alignment_file: { + // _is_null: false, + // }, + // }, + // }, + // }), + // ) + // .with('tomogram', () => + // where.push({ + // runs: { + // tomogram_voxel_spacings: { + // tomograms_aggregate: { + // count: { + // predicate: { + // _gt: 0, + // }, + // }, + // }, + // }, + // }, + // }), + // ) + // .exhaustive(), + // ) + // Number of Runs + // TODO: Implement when available in API. + // if (filterState.includedContents.numberOfRuns) { + // const runCount = +filterState.includedContents.numberOfRuns.slice(1) + // where.push({ + // runs_aggregate: { + // count: { + // predicate: { _gte: runCount }, + // }, + // }, + // }) + // } + + // NAME/ID SECTION + // Dataset IDs + const datasetId = + filterState.ids.dataset !== null + ? parseInt(filterState.ids.dataset) + : undefined + if (Number.isInteger(datasetId)) { + where.id = { + _eq: datasetId, + } + } + const empiarId = filterState.ids.empiar + const emdbId = filterState.ids.emdb + if (empiarId && emdbId) { + where.relatedDatabaseEntries = { + _regex: `(EMPIAR-${empiarId}.*EMD-${emdbId})|(EMD-${emdbId}.*EMPIAR-${empiarId})`, // Ignores order + } + } else if (empiarId) { + where.relatedDatabaseEntries = { + _regex: `EMPIAR-${empiarId}`, + } + } else if (emdbId) { + where.relatedDatabaseEntries = { + _regex: `EMD-${emdbId}`, + } + } + // Dataset Author + if (filterState.author.name || filterState.author.orcid) { + where.authors = {} + } + if (filterState.author.name) { + where.authors!.name = { + _ilike: `%${filterState.author.name}%`, + } + } + if (filterState.author.orcid) { + where.authors!.orcid = { + _ilike: `%${filterState.author.orcid}%`, + } + } + // Deposition ID + const depositionId = + filterState.ids.deposition !== null + ? parseInt(filterState.ids.deposition) + : undefined + if (Number.isInteger(depositionId)) { + where.depositionId = { + _eq: depositionId, + } + } + + // SAMPLE AND EXPERIMENT CONDITIONS SECTION + const { organismNames } = filterState.sampleAndExperimentConditions + if (organismNames.length > 0) { + where.organismName = { + _in: organismNames, + } + } + + // ANNOTATION METADATA SECTION + const { objectNames, objectId, objectShapeTypes } = filterState.annotation + if (objectNames.length > 0) { + // Object Name + where.runs!.annotations!.objectName = { + _in: objectNames, + } + } + // Object ID + if (objectId) { + where.runs!.annotations!.objectId = { + _eq: objectId, + } + } + // Object Shape Type + if (objectShapeTypes.length > 0) { + where.runs!.annotations!.annotationShapes = { + shapeType: { + _in: objectShapeTypes as Annotation_File_Shape_Type_Enum[], // TODO(bchu): Remove typecast. + }, + } + } + + // HARDWARE SECTION + if (filterState.hardware.cameraManufacturer) { + where.runs!.tiltseries!.cameraManufacturer = { + _eq: filterState.hardware.cameraManufacturer, + } + } + + // TILT SERIES METADATA SECTION + const tiltRangeMin = parseFloat(filterState.tiltSeries.min) + const tiltRangeMax = parseFloat(filterState.tiltSeries.max) + if (Number.isFinite(tiltRangeMin) || Number.isFinite(tiltRangeMax)) { + where.runs!.tiltseries!.tiltRange = { + _gte: Number.isFinite(tiltRangeMin) + ? tiltRangeMin + : DEFAULT_TILT_RANGE_MIN, + _lte: Number.isFinite(tiltRangeMax) + ? tiltRangeMax + : DEFAULT_TILT_RANGE_MAX, + } + } + + // TOMOGRAM METADATA SECTION + // Fiducial Alignment Status + if (filterState.tomogram.fiducialAlignmentStatus) { + where.runs!.tomograms!.fiducialAlignmentStatus = { + _eq: + filterState.tomogram.fiducialAlignmentStatus === 'true' + ? Fiducial_Alignment_Status_Enum.Fiducial + : Fiducial_Alignment_Status_Enum.NonFiducial, + } + } + // Reconstruction Method + if (filterState.tomogram.reconstructionMethod) { + where.runs!.tomograms!.reconstructionMethod = { + _eq: convertReconstructionMethodToV2( + filterState.tomogram.reconstructionMethod, + ), + } + } + // Reconstruction Software + if (filterState.tomogram.reconstructionSoftware) { + where.runs!.tomograms!.reconstructionSoftware = { + _eq: filterState.tomogram.reconstructionSoftware, + } + } + + return where +} + +function convertReconstructionMethodToV2( + v1: string, +): Tomogram_Reconstruction_Method_Enum { + switch (v1) { + case 'Fourier Space': + return Tomogram_Reconstruction_Method_Enum.FourierSpace + case 'SART': + return Tomogram_Reconstruction_Method_Enum.Sart + case 'SIRT': + return Tomogram_Reconstruction_Method_Enum.Sirt + case 'WBP': + return Tomogram_Reconstruction_Method_Enum.Wbp + case 'Unknown': + default: + return Tomogram_Reconstruction_Method_Enum.Unknown + } +} + +export async function getDatasetsV2({ + page, + titleOrderDirection, + searchText, + params, + client, +}: { + page: number + titleOrderDirection?: OrderBy + searchText?: string + params: URLSearchParams + client: ApolloClient +}): Promise> { + return client.query({ + query: GET_DATASETS_QUERY, + variables: { + filter: getFilter(getFilterState(params), searchText), + limit: MAX_PER_PAGE, + offset: (page - 1) * MAX_PER_PAGE, + // Default order is by release date. + orderBy: [ + titleOrderDirection + ? { title: titleOrderDirection } + : { + releaseDate: OrderBy.Desc, + }, + ], + }, + }) +} diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts index 8fc352226..36f0890ce 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts @@ -432,6 +432,7 @@ function getAnnotationShapesFilter( _eq: runId, }, }, + authors: {}, }, } @@ -457,9 +458,6 @@ function getAnnotationShapesFilter( // Author filters const { name, orcid } = filterState.author - if (name || orcid) { - where.annotation!.authors = {} - } if (name) { where.annotation!.authors!.name = { _ilike: `%${name}%`, diff --git a/frontend/packages/data-portal/app/hooks/useDatasets.ts b/frontend/packages/data-portal/app/hooks/useDatasets.ts index 61cdc5efc..73379af05 100644 --- a/frontend/packages/data-portal/app/hooks/useDatasets.ts +++ b/frontend/packages/data-portal/app/hooks/useDatasets.ts @@ -6,22 +6,22 @@ import { GetDatasetsDataQuery } from 'app/__generated__/graphql' export type Dataset = GetDatasetsDataQuery['datasets'][number] export function useDatasets() { - const { datasetsData: data } = useTypedLoaderData<{ - datasetsData: GetDatasetsDataQuery + const { v1 } = useTypedLoaderData<{ + v1: GetDatasetsDataQuery }>() return useMemo( () => ({ - datasets: data.datasets, - datasetCount: data.datasets_aggregate.aggregate?.count ?? 0, + datasets: v1.datasets, + datasetCount: v1.datasets_aggregate.aggregate?.count ?? 0, filteredDatasetCount: - data.filtered_datasets_aggregate.aggregate?.count ?? 0, + v1.filtered_datasets_aggregate.aggregate?.count ?? 0, }), [ - data.datasets, - data.datasets_aggregate.aggregate?.count, - data.filtered_datasets_aggregate.aggregate?.count, + v1.datasets, + v1.datasets_aggregate.aggregate?.count, + v1.filtered_datasets_aggregate.aggregate?.count, ], ) } diff --git a/frontend/packages/data-portal/app/hooks/useDatasetsFilterData.ts b/frontend/packages/data-portal/app/hooks/useDatasetsFilterData.ts index 76aaf47b4..6e3d89bd5 100644 --- a/frontend/packages/data-portal/app/hooks/useDatasetsFilterData.ts +++ b/frontend/packages/data-portal/app/hooks/useDatasetsFilterData.ts @@ -5,41 +5,39 @@ import { useTypedLoaderData } from 'remix-typedjson' import { GetDatasetsFilterDataQuery } from 'app/__generated__/graphql' export function useDatasetsFilterData() { - const { datasetsFilterData: data } = useTypedLoaderData<{ - datasetsFilterData: GetDatasetsFilterDataQuery + const { v1FilterValues: v1 } = useTypedLoaderData<{ + v1FilterValues: GetDatasetsFilterDataQuery }>() return useMemo( () => ({ - organismNames: data.organism_names + organismNames: v1.organism_names .map((value) => value.organism_name) .filter(isString), - cameraManufacturers: data.camera_manufacturers.map( + cameraManufacturers: v1.camera_manufacturers.map( (value) => value.camera_manufacturer, ), - reconstructionMethods: data.reconstruction_methods.map( + reconstructionMethods: v1.reconstruction_methods.map( (value) => value.reconstruction_method, ), - reconstructionSoftwares: data.reconstruction_softwares.map( + reconstructionSoftwares: v1.reconstruction_softwares.map( (value) => value.reconstruction_software, ), - objectNames: data.object_names.map((value) => value.object_name), + objectNames: v1.object_names.map((value) => value.object_name), - objectShapeTypes: data.object_shape_types.map( - (value) => value.shape_type, - ), + objectShapeTypes: v1.object_shape_types.map((value) => value.shape_type), }), [ - data.organism_names, - data.camera_manufacturers, - data.reconstruction_methods, - data.reconstruction_softwares, - data.object_names, - data.object_shape_types, + v1.organism_names, + v1.camera_manufacturers, + v1.reconstruction_methods, + v1.reconstruction_softwares, + v1.object_names, + v1.object_shape_types, ], ) } diff --git a/frontend/packages/data-portal/app/routes/browse-data.datasets.tsx b/frontend/packages/data-portal/app/routes/browse-data.datasets.tsx index 6404695d3..486b1f77f 100644 --- a/frontend/packages/data-portal/app/routes/browse-data.datasets.tsx +++ b/frontend/packages/data-portal/app/routes/browse-data.datasets.tsx @@ -2,7 +2,8 @@ import { CellHeaderDirection } from '@czi-sds/components' import { json, LoaderFunctionArgs } from '@remix-run/node' import { Order_By } from 'app/__generated__/graphql' -import { apolloClient } from 'app/apollo.server' +import { OrderBy } from 'app/__generated_v2__/graphql' +import { apolloClient, apolloClientV2 } from 'app/apollo.server' import { DatasetTable } from 'app/components/BrowseData' import { BrowseDataSearch } from 'app/components/BrowseData/BrowseDataSearch' import { DatasetFilter } from 'app/components/DatasetFilter' @@ -16,6 +17,7 @@ import { DATASET_FILTERS } from 'app/constants/filterQueryParams' import { QueryParams } from 'app/constants/query' import { getBrowseDatasets } from 'app/graphql/getBrowseDatasets.server' import { getDatasetsFilterData } from 'app/graphql/getDatasetsFilterData.server' +import { getDatasetsV2 } from 'app/graphql/getDatasetsV2.server' import { useDatasets } from 'app/hooks/useDatasets' import { useI18n } from 'app/hooks/useI18n' import { @@ -32,12 +34,18 @@ export async function loader({ request }: LoaderFunctionArgs) { const query = url.searchParams.get(QueryParams.Search) ?? '' let orderBy: Order_By | null = null + let orderByV2: OrderBy | undefined if (sort) { orderBy = sort === 'asc' ? Order_By.Asc : Order_By.Desc + orderByV2 = sort === 'asc' ? OrderBy.Asc : OrderBy.Desc } - const [datasetsResponse, datasetsFilterResponse] = await Promise.all([ + const [ + { data: responseV1 }, + { data: filterValuesResponseV1 }, + { data: responseV2 }, + ] = await Promise.all([ getBrowseDatasets({ orderBy, page, @@ -46,11 +54,19 @@ export async function loader({ request }: LoaderFunctionArgs) { params: url.searchParams, }), getDatasetsFilterData({ client: apolloClient }), + getDatasetsV2({ + page, + titleOrderDirection: orderByV2, + searchText: query, + params: url.searchParams, + client: apolloClientV2, + }), ]) return json({ - datasetsData: datasetsResponse.data, - datasetsFilterData: datasetsFilterResponse.data, + v1: responseV1, + v1FilterValues: filterValuesResponseV1, + v2: responseV2, }) } diff --git a/frontend/packages/eslint-config/typescript.cjs b/frontend/packages/eslint-config/typescript.cjs index d98965b4a..b7a3d5ea8 100644 --- a/frontend/packages/eslint-config/typescript.cjs +++ b/frontend/packages/eslint-config/typescript.cjs @@ -60,6 +60,9 @@ module.exports = { // Allow use of continue in loops 'no-continue': 'off', + // Rule only exists b/c of an edge case in IE8 + radix: 'off', + // Sometimes it's safe to call async functions and not handle their errors. '@typescript-eslint/no-misused-promises': 'off', // Allow us to use function/variable hoisting. From 325785055627343b2b3f97143d5ede4ae07b29cd Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Wed, 8 Jan 2025 09:28:27 -0800 Subject: [PATCH 25/35] fix: Fix deposition dropdown filters being broken (#1448) --- frontend/packages/data-portal/app/routes/depositions.$id.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/packages/data-portal/app/routes/depositions.$id.tsx b/frontend/packages/data-portal/app/routes/depositions.$id.tsx index 4adc4d1a3..fbe0976ba 100644 --- a/frontend/packages/data-portal/app/routes/depositions.$id.tsx +++ b/frontend/packages/data-portal/app/routes/depositions.$id.tsx @@ -105,7 +105,7 @@ export async function loader({ params, request }: LoaderFunctionArgs) { return typedjson({ depositionData: depositionResponse.data, - datasetsFilterData: datasetsFilterReponse.data, + v1FilterValues: datasetsFilterReponse.data, annotationMethodCounts, }) } From 2087cf676b8fd46ae39ecf39e5846e825895e574 Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Wed, 8 Jan 2025 09:28:58 -0800 Subject: [PATCH 26/35] fix: Never send empty argument objects to APIv2 (#1447) * fix sort --- .../app/graphql/getDatasetByIdV2.server.ts | 20 ++-- .../app/graphql/getDatasetsV2.server.ts | 51 ++++++---- .../app/graphql/getRunByIdDiffer.ts | 96 ++++++++++--------- .../app/graphql/getRunByIdV2.server.ts | 24 +++-- 4 files changed, 112 insertions(+), 79 deletions(-) diff --git a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts index a4fec8cd8..7e0b25aad 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts @@ -218,8 +218,6 @@ function getRunFilter( datasetId: { _eq: datasetId, }, - tiltseries: {}, - annotations: {}, } // Deposition filter: @@ -234,7 +232,8 @@ function getRunFilter( const tiltRangeMin = parseFloat(filterState.tiltSeries.min) const tiltRangeMax = parseFloat(filterState.tiltSeries.max) if (Number.isFinite(tiltRangeMin) || Number.isFinite(tiltRangeMax)) { - where.tiltseries!.tiltRange = { + where.tiltseries ??= {} + where.tiltseries.tiltRange = { _gte: Number.isFinite(tiltRangeMin) ? tiltRangeMin : DEFAULT_TILT_RANGE_MIN, @@ -244,7 +243,8 @@ function getRunFilter( } } if (filterState.tiltSeries.qualityScore.length > 0) { - where.tiltseries!.tiltSeriesQuality = { + where.tiltseries ??= {} + where.tiltseries.tiltSeriesQuality = { _in: filterState.tiltSeries.qualityScore .map(parseInt) .filter((val) => Number.isFinite(val)), @@ -253,15 +253,18 @@ function getRunFilter( // Annotation filters: if (filterState.includedContents.isGroundTruthEnabled) { - where.annotations!.groundTruthStatus = { _eq: true } + where.annotations ??= {} + where.annotations.groundTruthStatus = { _eq: true } } if (filterState.annotation.objectNames.length > 0) { - where.annotations!.objectName = { + where.annotations ??= {} + where.annotations.objectName = { _in: filterState.annotation.objectNames, } } if (filterState.annotation.objectShapeTypes.length > 0) { - where.annotations!.annotationShapes = { + where.annotations ??= {} + where.annotations.annotationShapes = { shapeType: { _in: filterState.annotation .objectShapeTypes as Annotation_File_Shape_Type_Enum[], // TODO(bchu): Remove typecast. @@ -269,7 +272,8 @@ function getRunFilter( } } if (filterState.annotation.objectId !== null) { - where.annotations!.objectId = { + where.annotations ??= {} + where.annotations.objectId = { _ilike: `%${filterState.annotation.objectId.replace(':', '_')}`, // _ is wildcard } } diff --git a/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts index 60d2f33d1..21a20fb39 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts @@ -87,9 +87,7 @@ function getFilter( filterState: FilterState, searchText?: string, ): DatasetWhereClause { - const where: DatasetWhereClause = { - runs: { annotations: {}, tiltseries: {}, tomograms: {} }, - } + const where: DatasetWhereClause = {} // Search by Dataset Name if (searchText) { @@ -101,7 +99,9 @@ function getFilter( // INCLUDED CONTENTS SECTION // Ground Truth Annotation if (filterState.includedContents.isGroundTruthEnabled) { - where.runs!.annotations!.groundTruthStatus = { + where.runs ??= { annotations: {} } + where.runs.annotations ??= {} + where.runs.annotations.groundTruthStatus = { _eq: true, } } @@ -201,16 +201,15 @@ function getFilter( } } // Dataset Author - if (filterState.author.name || filterState.author.orcid) { - where.authors = {} - } if (filterState.author.name) { - where.authors!.name = { + where.authors ??= {} + where.authors.name = { _ilike: `%${filterState.author.name}%`, } } if (filterState.author.orcid) { - where.authors!.orcid = { + where.authors ??= {} + where.authors.orcid = { _ilike: `%${filterState.author.orcid}%`, } } @@ -235,21 +234,27 @@ function getFilter( // ANNOTATION METADATA SECTION const { objectNames, objectId, objectShapeTypes } = filterState.annotation + // Object Name if (objectNames.length > 0) { - // Object Name - where.runs!.annotations!.objectName = { + where.runs ??= { annotations: {} } + where.runs.annotations ??= {} + where.runs.annotations.objectName = { _in: objectNames, } } // Object ID if (objectId) { - where.runs!.annotations!.objectId = { + where.runs ??= { annotations: {} } + where.runs.annotations ??= {} + where.runs.annotations.objectId = { _eq: objectId, } } // Object Shape Type if (objectShapeTypes.length > 0) { - where.runs!.annotations!.annotationShapes = { + where.runs ??= { annotations: {} } + where.runs.annotations ??= {} + where.runs.annotations.annotationShapes = { shapeType: { _in: objectShapeTypes as Annotation_File_Shape_Type_Enum[], // TODO(bchu): Remove typecast. }, @@ -258,7 +263,9 @@ function getFilter( // HARDWARE SECTION if (filterState.hardware.cameraManufacturer) { - where.runs!.tiltseries!.cameraManufacturer = { + where.runs ??= { tiltseries: {} } + where.runs.tiltseries ??= {} + where.runs.tiltseries.cameraManufacturer = { _eq: filterState.hardware.cameraManufacturer, } } @@ -267,7 +274,9 @@ function getFilter( const tiltRangeMin = parseFloat(filterState.tiltSeries.min) const tiltRangeMax = parseFloat(filterState.tiltSeries.max) if (Number.isFinite(tiltRangeMin) || Number.isFinite(tiltRangeMax)) { - where.runs!.tiltseries!.tiltRange = { + where.runs ??= { tiltseries: {} } + where.runs.tiltseries ??= {} + where.runs.tiltseries.tiltRange = { _gte: Number.isFinite(tiltRangeMin) ? tiltRangeMin : DEFAULT_TILT_RANGE_MIN, @@ -280,7 +289,9 @@ function getFilter( // TOMOGRAM METADATA SECTION // Fiducial Alignment Status if (filterState.tomogram.fiducialAlignmentStatus) { - where.runs!.tomograms!.fiducialAlignmentStatus = { + where.runs ??= { tomograms: {} } + where.runs.tomograms ??= {} + where.runs.tomograms.fiducialAlignmentStatus = { _eq: filterState.tomogram.fiducialAlignmentStatus === 'true' ? Fiducial_Alignment_Status_Enum.Fiducial @@ -289,7 +300,9 @@ function getFilter( } // Reconstruction Method if (filterState.tomogram.reconstructionMethod) { - where.runs!.tomograms!.reconstructionMethod = { + where.runs ??= { tomograms: {} } + where.runs.tomograms ??= {} + where.runs.tomograms.reconstructionMethod = { _eq: convertReconstructionMethodToV2( filterState.tomogram.reconstructionMethod, ), @@ -297,7 +310,9 @@ function getFilter( } // Reconstruction Software if (filterState.tomogram.reconstructionSoftware) { - where.runs!.tomograms!.reconstructionSoftware = { + where.runs ??= { tomograms: {} } + where.runs.tomograms ??= {} + where.runs.tomograms.reconstructionSoftware = { _eq: filterState.tomogram.reconstructionSoftware, } } diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts index 930d99bd5..6a0f36ad8 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts @@ -39,6 +39,8 @@ export function logIfHasDiff( methodLinkA.node.link.localeCompare(methodLinkB.node.link), ) } + // Tomograms are currently being sorted by the FE. + v2.tomograms.sort((tomogramA, tomogramB) => tomogramB.id - tomogramA.id) for (const tomogram of v2.tomograms) { // Delete fields that don't exist in V1. delete tomogram.alignment @@ -295,50 +297,52 @@ export function logIfHasDiff( }, }, })), - tomograms: v1.tomograms.map((tomogram) => ({ - ctfCorrected: tomogram.ctf_corrected, - fiducialAlignmentStatus: - tomogram.fiducial_alignment_status as Fiducial_Alignment_Status_Enum, - httpsMrcFile: tomogram.https_mrc_scale0, - id: tomogram.id, - isPortalStandard: false, - isAuthorSubmitted: tomogram.is_canonical, - keyPhotoThumbnailUrl: tomogram.key_photo_thumbnail_url, - keyPhotoUrl: tomogram.key_photo_url, - name: tomogram.name, - neuroglancerConfig: tomogram.neuroglancer_config, - processing: tomogram.processing as Tomogram_Processing_Enum, - processingSoftware: tomogram.processing_software, - reconstructionMethod: (tomogram.reconstruction_method === - 'Weighted back projection' - ? 'WBP' - : tomogram.reconstruction_method) as Tomogram_Reconstruction_Method_Enum, - reconstructionSoftware: tomogram.reconstruction_software, - s3MrcFile: tomogram.s3_mrc_scale0, - s3OmezarrDir: tomogram.s3_omezarr_dir, - sizeX: tomogram.size_x, - sizeY: tomogram.size_y, - sizeZ: tomogram.size_z, - voxelSpacing: tomogram.voxel_spacing, - tomogramVoxelSpacing: - tomogram.tomogram_voxel_spacing != null - ? { - id: tomogram.tomogram_voxel_spacing.id, - s3Prefix: tomogram.tomogram_voxel_spacing.s3_prefix!, - } - : undefined, - authors: { - edges: tomogram.authors.map((author) => ({ - node: { - primaryAuthorStatus: author.primary_author_status, - correspondingAuthorStatus: author.corresponding_author_status, - name: author.name, - email: author.email, - orcid: author.orcid, - }, - })), - }, - })), + tomograms: v1.tomograms + .map((tomogram) => ({ + ctfCorrected: tomogram.ctf_corrected, + fiducialAlignmentStatus: + tomogram.fiducial_alignment_status as Fiducial_Alignment_Status_Enum, + httpsMrcFile: tomogram.https_mrc_scale0, + id: tomogram.id, + isPortalStandard: false, + isAuthorSubmitted: tomogram.is_canonical, + keyPhotoThumbnailUrl: tomogram.key_photo_thumbnail_url, + keyPhotoUrl: tomogram.key_photo_url, + name: tomogram.name, + neuroglancerConfig: tomogram.neuroglancer_config, + processing: tomogram.processing as Tomogram_Processing_Enum, + processingSoftware: tomogram.processing_software, + reconstructionMethod: (tomogram.reconstruction_method === + 'Weighted back projection' + ? 'WBP' + : tomogram.reconstruction_method) as Tomogram_Reconstruction_Method_Enum, + reconstructionSoftware: tomogram.reconstruction_software, + s3MrcFile: tomogram.s3_mrc_scale0, + s3OmezarrDir: tomogram.s3_omezarr_dir, + sizeX: tomogram.size_x, + sizeY: tomogram.size_y, + sizeZ: tomogram.size_z, + voxelSpacing: tomogram.voxel_spacing, + tomogramVoxelSpacing: + tomogram.tomogram_voxel_spacing != null + ? { + id: tomogram.tomogram_voxel_spacing.id, + s3Prefix: tomogram.tomogram_voxel_spacing.s3_prefix!, + } + : undefined, + authors: { + edges: tomogram.authors.map((author) => ({ + node: { + primaryAuthorStatus: author.primary_author_status, + correspondingAuthorStatus: author.corresponding_author_status, + name: author.name, + email: author.email, + orcid: author.orcid, + }, + })), + }, + })) + .sort((tomogramA, tomogramB) => tomogramB.id - tomogramA.id), uniqueAnnotationSoftwares: { aggregate: v1.annotations_for_softwares .map((annotation) => ({ @@ -443,7 +447,9 @@ export function logIfHasDiff( console.log( `DIFF AT ${url} ======================================== ${JSON.stringify( v1Transformed, - )} ======================================== ${JSON.stringify(v2)}`, + )} ================================================================================ ${JSON.stringify( + v2, + )}`, ) } } diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts index 36f0890ce..522840442 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts @@ -432,7 +432,6 @@ function getAnnotationShapesFilter( _eq: runId, }, }, - authors: {}, }, } @@ -459,12 +458,16 @@ function getAnnotationShapesFilter( // Author filters const { name, orcid } = filterState.author if (name) { - where.annotation!.authors!.name = { + where.annotation ??= { authors: {} } + where.annotation.authors ??= {} + where.annotation.authors.name = { _ilike: `%${name}%`, } } if (orcid) { - where.annotation!.authors!.orcid = { + where.annotation ??= { authors: {} } + where.annotation.authors ??= {} + where.annotation.authors.orcid = { _ilike: `%${orcid}%`, } } @@ -473,29 +476,34 @@ function getAnnotationShapesFilter( const { objectNames, annotationSoftwares, methodTypes, objectId } = filterState.annotation if (objectNames.length > 0) { - where.annotation!.objectName = { + where.annotation ??= {} + where.annotation.objectName = { _in: objectNames, } } if (objectId) { - where.annotation!.objectId = { + where.annotation ??= {} + where.annotation.objectId = { _ilike: `%${objectId.replace(':', '_')}`, // _ is wildcard } } if (methodTypes.length > 0) { - where.annotation!.methodType = { + where.annotation ??= {} + where.annotation.methodType = { _in: methodTypes as Annotation_Method_Type_Enum[], } } if (annotationSoftwares.length > 0) { - where.annotation!.annotationSoftware = { + where.annotation ??= {} + where.annotation.annotationSoftware = { _in: annotationSoftwares, } } // Ground truth dividers if (groundTruthStatus !== undefined) { - where.annotation!.groundTruthStatus = { + where.annotation ??= {} + where.annotation.groundTruthStatus = { _eq: groundTruthStatus, } } From 8d258b73c1d5f535c08ecab1070e82504ccf79fb Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:15:18 -0800 Subject: [PATCH 27/35] fix: Remove non-null assertions in dataset page hook (#1450) --- .../data-portal/app/hooks/useDatasetById.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/frontend/packages/data-portal/app/hooks/useDatasetById.ts b/frontend/packages/data-portal/app/hooks/useDatasetById.ts index cdceaad4d..b896330cd 100644 --- a/frontend/packages/data-portal/app/hooks/useDatasetById.ts +++ b/frontend/packages/data-portal/app/hooks/useDatasetById.ts @@ -2,6 +2,7 @@ import { useTypedLoaderData } from 'remix-typedjson' import { GetDatasetByIdQuery } from 'app/__generated__/graphql' import { GetDatasetByIdV2Query } from 'app/__generated_v2__/graphql' +import { isDefined } from 'app/utils/nullish' export function useDatasetById() { const { v1, v2 } = useTypedLoaderData<{ @@ -13,13 +14,15 @@ export function useDatasetById() { const deposition = v2.depositions[0] - const objectNames = v2.annotationsAggregate.aggregate!.map( - (aggregate) => aggregate.groupBy!.objectName!, - ) + const objectNames = + v2.annotationsAggregate.aggregate + ?.map((aggregate) => aggregate.groupBy?.objectName) + .filter(isDefined) ?? [] - const objectShapeTypes = v2.annotationShapesAggregate.aggregate!.map( - (aggregate) => aggregate.groupBy!.shapeType!, - ) + const objectShapeTypes = + v2.annotationShapesAggregate.aggregate + ?.map((aggregate) => aggregate.groupBy?.shapeType) + .filter(isDefined) ?? [] return { dataset, From 2ac96b63c2980ed4af3a8cc818c825bea9ae5bfd Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:15:57 -0800 Subject: [PATCH 28/35] feat: Add diff detection for new datasets page query (#1446) * add = * lint --- .../data-portal/app/graphql/common.ts | 19 ++ .../app/graphql/getBrowseDatasets.server.ts | 17 +- .../app/graphql/getDatasetByIdDiffer.ts | 17 +- .../app/graphql/getDatasetsDiffer.ts | 251 ++++++++++++++++++ .../app/graphql/getDatasetsV2.server.ts | 34 +-- .../app/graphql/getRunByIdDiffer.ts | 23 +- .../app/routes/browse-data.datasets.tsx | 8 + .../data-portal/app/routes/datasets.$id.tsx | 4 +- .../data-portal/app/routes/runs.$id.tsx | 4 +- frontend/packages/data-portal/codegen.ts | 1 + 10 files changed, 329 insertions(+), 49 deletions(-) create mode 100644 frontend/packages/data-portal/app/graphql/getDatasetsDiffer.ts diff --git a/frontend/packages/data-portal/app/graphql/common.ts b/frontend/packages/data-portal/app/graphql/common.ts index 4bbff74aa..5baef1bc8 100644 --- a/frontend/packages/data-portal/app/graphql/common.ts +++ b/frontend/packages/data-portal/app/graphql/common.ts @@ -1,4 +1,5 @@ import { Depositions_Bool_Exp } from 'app/__generated__/graphql' +import { Tomogram_Reconstruction_Method_Enum } from 'app/__generated_v2__/graphql' export const depositionWithAnnotationFilter: Depositions_Bool_Exp = { annotations_aggregate: { @@ -9,3 +10,21 @@ export const depositionWithAnnotationFilter: Depositions_Bool_Exp = { }, }, } + +export function convertReconstructionMethodToV2( + v1: string, +): Tomogram_Reconstruction_Method_Enum { + switch (v1) { + case 'Fourier Space': + return Tomogram_Reconstruction_Method_Enum.FourierSpace + case 'SART': + return Tomogram_Reconstruction_Method_Enum.Sart + case 'SIRT': + return Tomogram_Reconstruction_Method_Enum.Sirt + case 'WBP': + return Tomogram_Reconstruction_Method_Enum.Wbp + case 'Unknown': + default: + return Tomogram_Reconstruction_Method_Enum.Unknown + } +} diff --git a/frontend/packages/data-portal/app/graphql/getBrowseDatasets.server.ts b/frontend/packages/data-portal/app/graphql/getBrowseDatasets.server.ts index 8c061c10f..aba89e2fb 100644 --- a/frontend/packages/data-portal/app/graphql/getBrowseDatasets.server.ts +++ b/frontend/packages/data-portal/app/graphql/getBrowseDatasets.server.ts @@ -12,13 +12,13 @@ const GET_DATASETS_DATA_QUERY = gql(` query GetDatasetsData( $limit: Int, $offset: Int, - $order_by: datasets_order_by!, + $order_by: [datasets_order_by!]!, $filter: datasets_bool_exp, ) { datasets( limit: $limit, offset: $offset, - order_by: [$order_by], + order_by: $order_by, where: $filter ) { id @@ -383,12 +383,15 @@ export async function getBrowseDatasets({ limit: MAX_PER_PAGE, offset: (page - 1) * MAX_PER_PAGE, - // Order by dataset title if orderBy is set, otherwise order by release date + // Default order primarily by release date. order_by: orderBy - ? { title: orderBy } - : { - release_date: Order_By.Desc, - }, + ? [{ title: orderBy }, { release_date: Order_By.Desc }] + : [ + { + release_date: Order_By.Desc, + }, + { title: Order_By.Asc }, + ], }, }) diff --git a/frontend/packages/data-portal/app/graphql/getDatasetByIdDiffer.ts b/frontend/packages/data-portal/app/graphql/getDatasetByIdDiffer.ts index 010c3d9d6..4114378d8 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetByIdDiffer.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetByIdDiffer.ts @@ -26,7 +26,9 @@ export function logIfHasDiff( } // Consistent sort order. run.annotationsAggregate?.aggregate?.sort((groupA, groupB) => - groupA.groupBy!.objectName!.localeCompare(groupB.groupBy!.objectName!), + String(groupA.groupBy!.objectName).localeCompare( + String(groupB.groupBy!.objectName), + ), ) } for (const annotationsAggreate of v2.annotationsAggregate.aggregate ?? []) { @@ -41,14 +43,19 @@ export function logIfHasDiff( } // Consistent sort order. v2.annotationsAggregate.aggregate?.sort((groupA, groupB) => - groupA.groupBy!.objectName!.localeCompare(groupB.groupBy!.objectName!), + String(groupA.groupBy!.objectName).localeCompare( + String(groupB.groupBy!.objectName), + ), ) v2.annotationShapesAggregate.aggregate?.sort((groupA, groupB) => - groupA.groupBy!.shapeType!.localeCompare(groupB.groupBy!.shapeType!), + String(groupA.groupBy!.shapeType).localeCompare( + String(groupB.groupBy!.shapeType), + ), ) v2.tiltseriesAggregate.aggregate?.sort( (groupA, groupB) => - groupA.groupBy!.tiltSeriesQuality! - groupB.groupBy!.tiltSeriesQuality!, + Number(groupA.groupBy!.tiltSeriesQuality) - + Number(groupB.groupBy!.tiltSeriesQuality), ) const v1Transformed: GetDatasetByIdV2Query = { @@ -270,7 +277,7 @@ export function logIfHasDiff( console.log( `DIFF AT ${url} ================================================================================ ${JSON.stringify( v1Transformed, - )} ================================================================================ ${JSON.stringify( + )} ================================================================================================================================================================ ${JSON.stringify( v2, )}`, ) diff --git a/frontend/packages/data-portal/app/graphql/getDatasetsDiffer.ts b/frontend/packages/data-portal/app/graphql/getDatasetsDiffer.ts new file mode 100644 index 000000000..c0ac4c28a --- /dev/null +++ b/frontend/packages/data-portal/app/graphql/getDatasetsDiffer.ts @@ -0,0 +1,251 @@ +import { diff } from 'deep-object-diff' + +import { + GetDatasetsDataQuery, + GetDatasetsFilterDataQuery, +} from 'app/__generated__/graphql' +import { + Annotation_File_Shape_Type_Enum, + GetDatasetsV2Query, +} from 'app/__generated_v2__/graphql' + +import { convertReconstructionMethodToV2 } from './common' + +/* eslint-disable no-console, no-param-reassign */ +export function logIfHasDiff( + url: string, + v1: GetDatasetsDataQuery, + v1FilterValues: GetDatasetsFilterDataQuery, + v2: GetDatasetsV2Query, +): void { + console.log('Checking for datasets query diffs') + + v2 = structuredClone(v2) + + // Counts not used. + // Create consistent sort order. + for (const dataset of v2.datasets) { + for (const annotationsAggregate of dataset.distinctObjectNames!.aggregate ?? + []) { + delete annotationsAggregate.count + } + dataset.distinctObjectNames!.aggregate!.sort((groupA, groupB) => + String(groupA.groupBy!.annotations!.objectName).localeCompare( + String(groupB.groupBy!.annotations!.objectName), + ), + ) + } + for (const group of v2.distinctOrganismNames.aggregate!) { + delete group.count + } + v2.distinctOrganismNames.aggregate!.sort((groupA, groupB) => + String(groupA.groupBy!.organismName).localeCompare( + String(groupB.groupBy!.organismName), + ), + ) + for (const group of v2.distinctCameraManufacturers.aggregate!) { + delete group.count + } + v2.distinctCameraManufacturers.aggregate!.sort((groupA, groupB) => + String(groupA.groupBy!.cameraManufacturer).localeCompare( + String(groupB.groupBy!.cameraManufacturer), + ), + ) + for (const group of v2.distinctReconstructionMethods.aggregate!) { + delete group.count + } + v2.distinctReconstructionMethods.aggregate!.sort((groupA, groupB) => + String(groupA.groupBy!.reconstructionMethod).localeCompare( + String(groupB.groupBy!.reconstructionMethod), + ), + ) + for (const group of v2.distinctReconstructionSoftwares.aggregate!) { + delete group.count + } + v2.distinctReconstructionSoftwares.aggregate = + v2.distinctReconstructionSoftwares + .aggregate!.filter( + // Bug in APIv2 returns this as a duplicate of 'AreTomo3 v2.0.4' + (group) => group.groupBy?.reconstructionSoftware !== 'AreTomo3_v2.0.4', + ) + .sort((groupA, groupB) => + String(groupA.groupBy!.reconstructionSoftware).localeCompare( + String(groupB.groupBy!.reconstructionSoftware), + ), + ) + for (const group of v2.distinctObjectNames.aggregate!) { + delete group.count + } + v2.distinctObjectNames.aggregate!.sort((groupA, groupB) => + String(groupA.groupBy!.objectName).localeCompare( + String(groupB.groupBy!.objectName), + ), + ) + for (const group of v2.distinctShapeTypes.aggregate!) { + delete group.count + } + v2.distinctShapeTypes.aggregate!.sort((groupA, groupB) => + String(groupA.groupBy!.shapeType).localeCompare( + String(groupB.groupBy!.shapeType), + ), + ) + + const v1Transformed: GetDatasetsV2Query = { + datasets: v1.datasets.map((dataset) => ({ + id: dataset.id, + title: dataset.title, + organismName: dataset.organism_name, + datasetPublications: dataset.dataset_publications, + keyPhotoThumbnailUrl: dataset.key_photo_thumbnail_url, + relatedDatabaseEntries: dataset.related_database_entries, + authors: { + edges: dataset.authors.map((author) => ({ + node: { + name: author.name, + primaryAuthorStatus: author.primary_author_status, + correspondingAuthorStatus: author.corresponding_author_status, + }, + })), + }, + runsCount: { + aggregate: + // Platformics returns an empty array if the count is 0. + dataset.runs_aggregate.aggregate!.count !== 0 + ? [ + { + count: dataset.runs_aggregate.aggregate!.count, + }, + ] + : [], + }, + distinctObjectNames: { + aggregate: [ + ...new Set( + dataset.runs.flatMap((run) => + run.tomogram_voxel_spacings.flatMap((voxelSpacing) => + voxelSpacing.annotations.map( + (annotation) => annotation.object_name, + ), + ), + ), + ), + ] + .map((distinctObjectName) => ({ + groupBy: { + annotations: { + objectName: distinctObjectName, + }, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.annotations.objectName.localeCompare( + groupB.groupBy.annotations.objectName, + ), + ), + }, + })), + totalDatasetsCount: { + aggregate: [ + { + count: v1.datasets_aggregate.aggregate!.count, + }, + ], + }, + filteredDatasetsCount: { + aggregate: [ + { + count: v1.filtered_datasets_aggregate.aggregate!.count, + }, + ], + }, + distinctOrganismNames: { + aggregate: v1FilterValues.organism_names + .map((organismName) => ({ + groupBy: { + organismName: organismName.organism_name, + }, + })) + .sort((groupA, groupB) => + String(groupA.groupBy.organismName).localeCompare( + String(groupB.groupBy.organismName), + ), + ), + }, + distinctCameraManufacturers: { + aggregate: v1FilterValues.camera_manufacturers + .map((cameraManufacturer) => ({ + groupBy: { + cameraManufacturer: cameraManufacturer.camera_manufacturer, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.cameraManufacturer.localeCompare( + groupB.groupBy.cameraManufacturer, + ), + ), + }, + distinctReconstructionMethods: { + aggregate: v1FilterValues.reconstruction_methods + .map((reconstructionMethod) => ({ + groupBy: { + reconstructionMethod: convertReconstructionMethodToV2( + reconstructionMethod.reconstruction_method, + ), + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.reconstructionMethod.localeCompare( + groupB.groupBy.reconstructionMethod, + ), + ), + }, + distinctReconstructionSoftwares: { + aggregate: v1FilterValues.reconstruction_softwares + .map((reconstructionSoftware) => ({ + groupBy: { + reconstructionSoftware: + reconstructionSoftware.reconstruction_software, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.reconstructionSoftware.localeCompare( + groupB.groupBy.reconstructionSoftware, + ), + ), + }, + distinctObjectNames: { + aggregate: v1FilterValues.object_names + .map((objectName) => ({ + groupBy: { + objectName: objectName.object_name, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.objectName.localeCompare(groupB.groupBy.objectName), + ), + }, + distinctShapeTypes: { + aggregate: v1FilterValues.object_shape_types + .map((shapeType) => ({ + groupBy: { + shapeType: shapeType.shape_type as Annotation_File_Shape_Type_Enum, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.shapeType.localeCompare(groupB.groupBy.shapeType), + ), + }, + } + + const diffObject = diff(v1Transformed, v2) + + if (Object.keys(diffObject).length > 0) { + console.log( + `DIFF AT ${url} ================================================================================ ${JSON.stringify( + v1Transformed, + )} ================================================================================================================================================================================================================================================================================================================================ ${JSON.stringify( + v2, + )}`, + ) + } +} diff --git a/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts index 21a20fb39..dbfffad43 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts @@ -11,7 +11,6 @@ import { Fiducial_Alignment_Status_Enum, GetDatasetsV2Query, OrderBy, - Tomogram_Reconstruction_Method_Enum, } from 'app/__generated_v2__/graphql' import { MAX_PER_PAGE } from 'app/constants/pagination' import { @@ -20,6 +19,8 @@ import { } from 'app/constants/tiltSeries' import { FilterState, getFilterState } from 'app/hooks/useFilter' +import { convertReconstructionMethodToV2 } from './common' + const GET_DATASETS_QUERY = gql(` query GetDatasetsV2( $limit: Int, @@ -320,24 +321,6 @@ function getFilter( return where } -function convertReconstructionMethodToV2( - v1: string, -): Tomogram_Reconstruction_Method_Enum { - switch (v1) { - case 'Fourier Space': - return Tomogram_Reconstruction_Method_Enum.FourierSpace - case 'SART': - return Tomogram_Reconstruction_Method_Enum.Sart - case 'SIRT': - return Tomogram_Reconstruction_Method_Enum.Sirt - case 'WBP': - return Tomogram_Reconstruction_Method_Enum.Wbp - case 'Unknown': - default: - return Tomogram_Reconstruction_Method_Enum.Unknown - } -} - export async function getDatasetsV2({ page, titleOrderDirection, @@ -357,14 +340,15 @@ export async function getDatasetsV2({ filter: getFilter(getFilterState(params), searchText), limit: MAX_PER_PAGE, offset: (page - 1) * MAX_PER_PAGE, - // Default order is by release date. - orderBy: [ - titleOrderDirection - ? { title: titleOrderDirection } - : { + // Default order primarily by release date. + orderBy: titleOrderDirection + ? [ + { title: titleOrderDirection }, + { releaseDate: OrderBy.Desc, }, - ], + ] + : [{ releaseDate: OrderBy.Desc }, { title: OrderBy.Asc }], }, }) } diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts index 6a0f36ad8..ab79ae736 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts @@ -74,22 +74,29 @@ export function logIfHasDiff( } // Consistent sort order. v2.uniqueAnnotationSoftwares.aggregate?.sort((gropuByA, groupByB) => - gropuByA.groupBy!.annotationSoftware!.localeCompare( - groupByB.groupBy!.annotationSoftware!, + String(gropuByA.groupBy!.annotationSoftware).localeCompare( + String(groupByB.groupBy!.annotationSoftware), ), ) v2.uniqueObjectNames.aggregate?.sort((groupA, groupB) => - groupA.groupBy!.objectName!.localeCompare(groupB.groupBy!.objectName!), + String(groupA.groupBy!.objectName).localeCompare( + String(groupB.groupBy!.objectName), + ), ) v2.uniqueShapeTypes.aggregate?.sort((groupA, groupB) => - groupA.groupBy!.shapeType!.localeCompare(groupB.groupBy!.shapeType!), + String(groupA.groupBy!.shapeType).localeCompare( + String(groupB.groupBy!.shapeType), + ), ) v2.uniqueResolutions.aggregate?.sort( (groupA, groupB) => - groupA.groupBy!.voxelSpacing! - groupB.groupBy!.voxelSpacing!, + Number(groupA.groupBy!.voxelSpacing) - + Number(groupB.groupBy!.voxelSpacing), ) v2.uniqueProcessingMethods.aggregate?.sort((groupA, groupB) => - groupA.groupBy!.processing!.localeCompare(groupB.groupBy!.processing!), + String(groupA.groupBy!.processing).localeCompare( + String(groupB.groupBy!.processing), + ), ) const v1Transformed: GetRunByIdV2Query = { @@ -351,8 +358,8 @@ export function logIfHasDiff( }, })) .sort((groupByA, groupByB) => - groupByA.groupBy.annotationSoftware!.localeCompare( - groupByB.groupBy.annotationSoftware!, + String(groupByA.groupBy.annotationSoftware).localeCompare( + String(groupByB.groupBy.annotationSoftware), ), ), }, diff --git a/frontend/packages/data-portal/app/routes/browse-data.datasets.tsx b/frontend/packages/data-portal/app/routes/browse-data.datasets.tsx index 486b1f77f..2fe674e4b 100644 --- a/frontend/packages/data-portal/app/routes/browse-data.datasets.tsx +++ b/frontend/packages/data-portal/app/routes/browse-data.datasets.tsx @@ -16,6 +16,7 @@ import { import { DATASET_FILTERS } from 'app/constants/filterQueryParams' import { QueryParams } from 'app/constants/query' import { getBrowseDatasets } from 'app/graphql/getBrowseDatasets.server' +import { logIfHasDiff } from 'app/graphql/getDatasetsDiffer' import { getDatasetsFilterData } from 'app/graphql/getDatasetsFilterData.server' import { getDatasetsV2 } from 'app/graphql/getDatasetsV2.server' import { useDatasets } from 'app/hooks/useDatasets' @@ -63,6 +64,13 @@ export async function loader({ request }: LoaderFunctionArgs) { }), ]) + try { + logIfHasDiff(request.url, responseV1, filterValuesResponseV1, responseV2) + } catch (error) { + // eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any + console.log(`DIFF ERROR: ${(error as any)?.stack}`) + } + return json({ v1: responseV1, v1FilterValues: filterValuesResponseV1, diff --git a/frontend/packages/data-portal/app/routes/datasets.$id.tsx b/frontend/packages/data-portal/app/routes/datasets.$id.tsx index 19ce9c1d4..0b03072c2 100644 --- a/frontend/packages/data-portal/app/routes/datasets.$id.tsx +++ b/frontend/packages/data-portal/app/routes/datasets.$id.tsx @@ -66,8 +66,8 @@ export async function loader({ params, request }: LoaderFunctionArgs) { try { logIfHasDiff(request.url, responseV1, responseV2) } catch (error) { - // eslint-disable-next-line no-console, @typescript-eslint/restrict-template-expressions - console.log(`DIFF ERROR: ${error}`) + // eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any + console.log(`DIFF ERROR: ${(error as any)?.stack}`) } return json({ diff --git a/frontend/packages/data-portal/app/routes/runs.$id.tsx b/frontend/packages/data-portal/app/routes/runs.$id.tsx index 287f20c04..d1b7847b8 100644 --- a/frontend/packages/data-portal/app/routes/runs.$id.tsx +++ b/frontend/packages/data-portal/app/routes/runs.$id.tsx @@ -75,8 +75,8 @@ export async function loader({ request, params }: LoaderFunctionArgs) { try { logIfHasDiff(request.url, responseV1, responseV2) } catch (error) { - // eslint-disable-next-line no-console, @typescript-eslint/restrict-template-expressions - console.log(`DIFF ERROR: ${error}`) + // eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any + console.log(`DIFF ERROR: ${(error as any)?.stack}`) } return json({ diff --git a/frontend/packages/data-portal/codegen.ts b/frontend/packages/data-portal/codegen.ts index 7f0781eb9..6945d641e 100644 --- a/frontend/packages/data-portal/codegen.ts +++ b/frontend/packages/data-portal/codegen.ts @@ -36,6 +36,7 @@ const config: CodegenConfig = { presetConfig: { gqlTagName: 'gql', + fragmentMasking: false, }, config: { From b1558ba209c0af68f6d2d054e814ba060dfd7970 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 23:55:18 +0000 Subject: [PATCH 29/35] chore(main): release web 1.40.0 (#1441) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- frontend/CHANGELOG.md | 20 ++++++++++++++++++++ frontend/package.json | 2 +- release-please.manifest.json | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index dca2528e3..701f33958 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [1.40.0](https://github.com/chanzuckerberg/cryoet-data-portal/compare/web-v1.39.0...web-v1.40.0) (2025-01-09) + + +### ✨ Features + +* Add diff detection for new datasets page query ([#1446](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1446)) ([2ac96b6](https://github.com/chanzuckerberg/cryoet-data-portal/commit/2ac96b63c2980ed4af3a8cc818c825bea9ae5bfd)) +* Migrate datasets page query ([#1438](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1438)) ([d634ebd](https://github.com/chanzuckerberg/cryoet-data-portal/commit/d634ebd72d6f907b06586a58b6977f2f803a2b07)) + + +### 🐞 Bug Fixes + +* Fix deposition dropdown filters being broken ([#1448](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1448)) ([3257850](https://github.com/chanzuckerberg/cryoet-data-portal/commit/325785055627343b2b3f97143d5ede4ae07b29cd)) +* Never send empty argument objects to APIv2 ([#1447](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1447)) ([2087cf6](https://github.com/chanzuckerberg/cryoet-data-portal/commit/2087cf676b8fd46ae39ecf39e5846e825895e574)) +* Remove non-null assertions in dataset page hook ([#1450](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1450)) ([8d258b7](https://github.com/chanzuckerberg/cryoet-data-portal/commit/8d258b73c1d5f535c08ecab1070e82504ccf79fb)) + + +### 🧪 Tests + +* filter components unit tests ([#1436](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1436)) ([1acbf30](https://github.com/chanzuckerberg/cryoet-data-portal/commit/1acbf3074de170ea8891fd6bb07b5cbba64b45e0)) + ## [1.39.0](https://github.com/chanzuckerberg/cryoet-data-portal/compare/web-v1.38.0...web-v1.39.0) (2025-01-03) diff --git a/frontend/package.json b/frontend/package.json index ea38019a2..661c77f38 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "1.39.0", + "version": "1.40.0", "scripts": { "preinstall": "npx only-allow pnpm", "build": "pnpm -r build", diff --git a/release-please.manifest.json b/release-please.manifest.json index 432e113ad..f931a28ba 100644 --- a/release-please.manifest.json +++ b/release-please.manifest.json @@ -1,4 +1,4 @@ { - "frontend": "1.39.0", + "frontend": "1.40.0", "client/python/cryoet_data_portal": "4.3.0" } From 4fee05c6a65b389fba53cbdd1ebeb5b71f9c452e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Melissa=20Weber=20Mendon=C3=A7a?= Date: Mon, 13 Jan 2025 17:23:38 -0300 Subject: [PATCH 30/35] feat: Add plausible analytics tracking to pages (#1459) --- docs/_templates/layout.html | 9 +++++++++ docs/conf.py | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 docs/_templates/layout.html diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 000000000..16c42f147 --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,9 @@ +{# Import the theme's layout. #} +{% extends '!layout.html' %} + +{%- block extrahead %} +{# Add custom things to the head HTML tag #} + +{# Call the parent block #} +{{ super() }} +{%- endblock %} diff --git a/docs/conf.py b/docs/conf.py index f1f46a5ba..bdc52a617 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -110,7 +110,6 @@ "text": "Inter", # used for all the pages' text "code": "Roboto Mono", # used for literal code blocks }, - # "analytics": {"provider": "google", "property": "G-XXXXXXXXXX"}, } # Remove icons from toc elements in API page From 4e3c156aae40bed62d3bdc5a519f8f33ef13509c Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Mon, 13 Jan 2025 12:43:31 -0800 Subject: [PATCH 31/35] chore: Refactor datasets filter values fragment (#1456) --- .../getDatasetsFilterValuesV2.server.ts | 42 ++++++++++++------- .../app/graphql/getDatasetsV2.server.ts | 26 +++++------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts b/frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts index e1d02e4eb..233bf6e94 100644 --- a/frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts @@ -1,13 +1,30 @@ import { gql } from 'app/__generated_v2__' /** - * Shares filter options queries between datasets and deposition pages (filters are near identical). + * Shares aggregate queries between datasets and deposition pages (the 2 pages are very similar). * - * Parent query must define $depositionFilter. + * Parent query must define the following variables: + * - $datasetsFilter + * - $datasetsByDepositionFilter + * - $tiltseriesByDepositionFilter + * - $tomogramsByDepositionFilter + * - $annotationsByDepositionFilter + * - $annotationShapesByDepositionFilter */ -export const GET_DATASETS_FILTER_VALUES_FRAGMENT = gql(` - fragment DatasetsFilterValues on Query { - distinctOrganismNames: datasetsAggregate(where: { depositionId: $depositionFilter }) { +export const GET_DATASETS_AGGREGATES_FRAGMENT = gql(` + fragment DatasetsAggregates on Query { + filteredDatasetsCount: datasetsAggregate(where: $datasetsFilter) { + aggregate { + count + } + } + totalDatasetsCount: datasetsAggregate(where: $datasetsByDepositionFilter) { + aggregate { + count + } + } + + distinctOrganismNames: datasetsAggregate(where: $datasetsByDepositionFilter) { aggregate { count groupBy { @@ -15,8 +32,7 @@ export const GET_DATASETS_FILTER_VALUES_FRAGMENT = gql(` } } } - - distinctCameraManufacturers: tiltseriesAggregate(where: { depositionId: $depositionFilter }) { + distinctCameraManufacturers: tiltseriesAggregate(where: $tiltseriesByDepositionFilter) { aggregate { count groupBy { @@ -24,8 +40,7 @@ export const GET_DATASETS_FILTER_VALUES_FRAGMENT = gql(` } } } - - distinctReconstructionMethods: tomogramsAggregate(where: { depositionId: $depositionFilter }) { + distinctReconstructionMethods: tomogramsAggregate(where: $tomogramsByDepositionFilter) { aggregate { count groupBy { @@ -33,8 +48,7 @@ export const GET_DATASETS_FILTER_VALUES_FRAGMENT = gql(` } } } - - distinctReconstructionSoftwares: tomogramsAggregate(where: { depositionId: $depositionFilter }) { + distinctReconstructionSoftwares: tomogramsAggregate(where: $tomogramsByDepositionFilter) { aggregate { count groupBy { @@ -42,8 +56,7 @@ export const GET_DATASETS_FILTER_VALUES_FRAGMENT = gql(` } } } - - distinctObjectNames: annotationsAggregate(where: { depositionId: $depositionFilter }) { + distinctObjectNames: annotationsAggregate(where: $annotationsByDepositionFilter) { aggregate { count groupBy { @@ -51,8 +64,7 @@ export const GET_DATASETS_FILTER_VALUES_FRAGMENT = gql(` } } } - - distinctShapeTypes: annotationShapesAggregate(where: { annotation: { depositionId: $depositionFilter } }) { + distinctShapeTypes: annotationShapesAggregate(where: $annotationShapesByDepositionFilter) { aggregate { count groupBy { diff --git a/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts index dbfffad43..1cbeafcb2 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts @@ -26,11 +26,16 @@ const GET_DATASETS_QUERY = gql(` $limit: Int, $offset: Int, $orderBy: [DatasetOrderByClause!]!, - $filter: DatasetWhereClause!, - $depositionFilter: IntComparators # Unused, but must be defined because DatasetsFilterValues references it. + $datasetsFilter: DatasetWhereClause!, + # Unused, but must be defined because DatasetsAggregates references them: + $datasetsByDepositionFilter: DatasetWhereClause, + $tiltseriesByDepositionFilter: TiltseriesWhereClause, + $tomogramsByDepositionFilter: TomogramWhereClause, + $annotationsByDepositionFilter: AnnotationWhereClause, + $annotationShapesByDepositionFilter: AnnotationShapeWhereClause ) { datasets( - where: $filter + where: $datasetsFilter orderBy: $orderBy, limitOffset: { limit: $limit, @@ -69,18 +74,7 @@ const GET_DATASETS_QUERY = gql(` } } - totalDatasetsCount: datasetsAggregate { - aggregate { - count - } - } - filteredDatasetsCount: datasetsAggregate(where: $filter) { - aggregate { - count - } - } - - ...DatasetsFilterValues + ...DatasetsAggregates } `) @@ -337,7 +331,7 @@ export async function getDatasetsV2({ return client.query({ query: GET_DATASETS_QUERY, variables: { - filter: getFilter(getFilterState(params), searchText), + datasetsFilter: getFilter(getFilterState(params), searchText), limit: MAX_PER_PAGE, offset: (page - 1) * MAX_PER_PAGE, // Default order primarily by release date. From 550869961ddb469abb80732f92b382740d96c93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Melissa=20Weber=20Mendon=C3=A7a?= Date: Mon, 13 Jan 2025 20:40:21 -0300 Subject: [PATCH 32/35] docs: Add anchors to FAQ questions (#1458) --- docs/cryoet_data_portal_docsite_faq.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/cryoet_data_portal_docsite_faq.md b/docs/cryoet_data_portal_docsite_faq.md index ca77ea5c7..5f604cf26 100644 --- a/docs/cryoet_data_portal_docsite_faq.md +++ b/docs/cryoet_data_portal_docsite_faq.md @@ -6,7 +6,7 @@ hide-navigation: true We hope these answers will help you get the most out of the CryoET Data Portal! -:::{admonition} How do I get help with using the Data Portal? +:::{admonition} How do I get help with using the Data Portal? :class: czi-faq :name: get-help :collapsible: @@ -14,7 +14,7 @@ We hope these answers will help you get the most out of the CryoET Data Portal! Did you encounter a bug, error, or other issue while using the portal? [Submit an issue on Github](https://github.com/chanzuckerberg/cryoet-data-portal/issues/new?assignees=&labels=bug&projects=&template=bug.md&title=) to let us know! ::: -:::{admonition} How do I submit an issue on Github? +:::{admonition} How do I submit an issue on Github?
:class: czi-faq :name: submit-issue :collapsible: @@ -23,7 +23,7 @@ To submit an issue, you'll need to create a [free Github account](https://github For more information about submiting issues on Github, please refer to [Github's documentation](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-an-issue#creating-an-issue-from-a-repository). ::: -:::{admonition} What are datasets, runs, and annotations in the Data Portal? +:::{admonition} What are datasets, runs, and annotations in the Data Portal? :class: czi-faq :name: data-schema :collapsible: @@ -37,7 +37,7 @@ The CryoET Data Portal uses the following data schema: You can refer to a graphic of the [data schema here](cryoet_data_portal_docsite_data). ::: -:::{admonition} How do I download data using Amazon Web Services (AWS)? +:::{admonition} How do I download data using Amazon Web Services (AWS)? :class: czi-faq :name: download-aws :collapsible: @@ -67,21 +67,21 @@ aws s3 cp --no-sign-request s3://cryoet-data-portal-public/10000/TS_026/Tomogram In the above example, the download happened very quickly because the file was only about 1 kB in size. However, typical tomograms are multiple GB, so expect downloading to take 30-60 mins for a single tomogram for a given run, but downloading could take as long as days depending on the number and sizes of the files. To speed up download, you can follow [these instructions to optimize download speed](cryoet_data_portal_docsite_aws.md#optimize-download-speed). ::: -:::{admonition} How do I use Neuroglancer to visualize tomograms with their annotations? +:::{admonition} How do I use Neuroglancer to visualize tomograms with their annotations? :class: czi-faq :name: visualize-neuroglancer :collapsible: All tomograms in the Data Portal are viewable in Neuroglancer along with their annotations. You can open a tomogram in Neuroglancer by clicking the blue `View Tomogram` button on any run page in the Portal. This will open an instance of Neuroglancer in a separate tab of your browser with the selected data along with their annotations already loaded. For more information about visualizing data with Neuroglancer, check out our [Quickstart guide](neuroglancer_quickstart) or the [documentation from Connectomics](https://connectomics.readthedocs.io/en/latest/external/neuroglancer.html#basic-usage), the team that develops Neuroglancer. ::: -:::{admonition} How do I use napari to visualize tomograms with their annotations? +:::{admonition} How do I use napari to visualize tomograms with their annotations? :class: czi-faq :name: visualize-napari :collapsible: The CryoET Data Portal napari plugin can be used to visualize tomograms, annotations, and metadata. Refer to [this documentation](https://github.com/chanzuckerberg/napari-cryoet-data-portal#usage) to learn about how to use the plugin and to [this page](cryoet_data_portal_docsite_napari) to learn more about napari and CryoET Data Portal. ::: -:::{admonition} How do I download data using the Portal's API? +:::{admonition} How do I download data using the Portal's API? :class: czi-faq :name: download-api :collapsible: @@ -107,7 +107,7 @@ tomo.download_omezarr() For more examples of downloading data with the API, check out the [tutorial here](cryoet_data_portal_docsite_quick_start.md#api-methods-overview). The Data Portal API reference can be found [here](python-api). ::: -:::{admonition} How do I use the Portal's API to select data? +:::{admonition} How do I use the Portal's API to select data? :class: czi-faq :name: select-api :collapsible: @@ -135,7 +135,7 @@ for run in runs_list: For more examples of using the `find` operator, check out the [tutorial here](cryoet_data_portal_docsite_quick_start.md#examples). The Data Portal API reference can be found [here](python-api). ::: -:::{admonition} What is the meaning of the tilt series quality score? +:::{admonition} What is the meaning of the tilt series quality score? :class: czi-faq :name: tilt-series-quality :collapsible: @@ -150,7 +150,7 @@ The tilt series quality score/rating is a relative subjective scale meant for co | 1 | Low | Not useful for analysis with current tools (not alignable), useful as a test case for problematic data only. | ::: -:::{admonition} What is the dataset identifier and Portal ID? +:::{admonition} What is the dataset identifier and Portal ID? :class: czi-faq :name: dataset-identifier :collapsible: @@ -159,7 +159,7 @@ The dataset identifier in the API refers to the Portal ID provided in the Portal Descriptions of all terminology and metadata used in the Portal is provided [here](python-api). ::: -:::{admonition} Which annotations are displayed with a tomogram in Neuroglancer? +:::{admonition} Which annotations are displayed with a tomogram in Neuroglancer? :class: czi-faq :name: default-annotations :collapsible: @@ -170,7 +170,7 @@ There is no definitive rule for which annotations are displayed in the Neuroglan The CryoET Data Portal napari plugin can be used to visualize tomograms, annotations, and metadata. Refer to [this documentation](https://github.com/chanzuckerberg/napari-cryoet-data-portal#usage) to learn about how to use the plugin and to [this page](cryoet_data_portal_docsite_napari) to learn more about napari and CryoET Data Portal. ::: -:::{admonition} How do I contribute data to the Portal? +:::{admonition} How do I contribute data to the Portal? :class: czi-faq :name: contribute-data :collapsible: From 0f26b64476cd1670055cc2e7ff9d6de8de58131a Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Tue, 14 Jan 2025 10:24:55 -0800 Subject: [PATCH 33/35] fix: Fix deposition filter on run page (#1466) --- .../data-portal/app/graphql/getDatasetByIdV2.server.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts index 7e0b25aad..408f53500 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts @@ -223,9 +223,8 @@ function getRunFilter( // Deposition filter: const depositionId = +(filterState.ids.deposition ?? Number.NaN) if (!Number.isNaN(depositionId) && depositionId > 0) { - where.dataset = { - depositionId: { _eq: depositionId }, - } + where.annotations ??= {} + where.annotations.depositionId = { _eq: depositionId } } // Tilt series filters: From c55bad82130062a135ad876e82385ac44e848963 Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:28:45 -0800 Subject: [PATCH 34/35] feat: Convert deposition page query to V2 (#1452) * lint * v1 --- .../data-portal/app/graphql/common.ts | 258 +++++++++++++++++- ...r.ts => getDatasetsAggregatesV2.server.ts} | 12 +- .../app/graphql/getDatasetsV2.server.ts | 258 +----------------- .../app/graphql/getDepositionById.server.ts | 16 +- .../app/graphql/getDepositionByIdV2.server.ts | 185 +++++++++++++ .../app/hooks/useDepositionById.ts | 25 +- .../app/routes/depositions.$id.tsx | 31 ++- 7 files changed, 502 insertions(+), 283 deletions(-) rename frontend/packages/data-portal/app/graphql/fragments/{getDatasetsFilterValuesV2.server.ts => getDatasetsAggregatesV2.server.ts} (83%) create mode 100644 frontend/packages/data-portal/app/graphql/getDepositionByIdV2.server.ts diff --git a/frontend/packages/data-portal/app/graphql/common.ts b/frontend/packages/data-portal/app/graphql/common.ts index 5baef1bc8..1cc3f9a06 100644 --- a/frontend/packages/data-portal/app/graphql/common.ts +++ b/frontend/packages/data-portal/app/graphql/common.ts @@ -1,5 +1,15 @@ import { Depositions_Bool_Exp } from 'app/__generated__/graphql' -import { Tomogram_Reconstruction_Method_Enum } from 'app/__generated_v2__/graphql' +import { + Annotation_File_Shape_Type_Enum, + DatasetWhereClause, + Fiducial_Alignment_Status_Enum, + Tomogram_Reconstruction_Method_Enum, +} from 'app/__generated_v2__/graphql' +import { + DEFAULT_TILT_RANGE_MAX, + DEFAULT_TILT_RANGE_MIN, +} from 'app/constants/tiltSeries' +import { FilterState } from 'app/hooks/useFilter' export const depositionWithAnnotationFilter: Depositions_Bool_Exp = { annotations_aggregate: { @@ -28,3 +38,249 @@ export function convertReconstructionMethodToV2( return Tomogram_Reconstruction_Method_Enum.Unknown } } + +export interface GetDatasetsFilterParams { + filterState: FilterState + depositionId?: number + searchText?: string +} + +export function getDatasetsFilter({ + filterState, + depositionId, + searchText, +}: GetDatasetsFilterParams): DatasetWhereClause { + const where: DatasetWhereClause = {} + + // Search by Dataset Name + if (searchText) { + where.title = { + _ilike: `%${searchText}%`, + } + } + + // INCLUDED CONTENTS SECTION + // Ground Truth Annotation + if (filterState.includedContents.isGroundTruthEnabled) { + where.runs ??= { annotations: {} } + where.runs.annotations ??= {} + where.runs.annotations.groundTruthStatus = { + _eq: true, + } + } + // Available Files + // TODO(bchu): Implement when available in API. + // filterState.includedContents.availableFiles.forEach((file) => + // match(file) + // .with('raw-frames', () => + // where.push({ + // runs: { + // tiltseries: { + // frames_count: { + // _gt: 0, + // }, + // }, + // }, + // }), + // ) + // .with('tilt-series', () => + // where.push({ + // runs: { + // tiltseries_aggregate: { + // count: { + // predicate: { + // _gt: 0, + // }, + // }, + // }, + // }, + // }), + // ) + // .with('tilt-series-alignment', () => + // where.push({ + // runs: { + // tiltseries: { + // https_alignment_file: { + // _is_null: false, + // }, + // }, + // }, + // }), + // ) + // .with('tomogram', () => + // where.push({ + // runs: { + // tomogram_voxel_spacings: { + // tomograms_aggregate: { + // count: { + // predicate: { + // _gt: 0, + // }, + // }, + // }, + // }, + // }, + // }), + // ) + // .exhaustive(), + // ) + // Number of Runs + // TODO: Implement when available in API. + // if (filterState.includedContents.numberOfRuns) { + // const runCount = +filterState.includedContents.numberOfRuns.slice(1) + // where.push({ + // runs_aggregate: { + // count: { + // predicate: { _gte: runCount }, + // }, + // }, + // }) + // } + + // NAME/ID SECTION + // Dataset IDs + const datasetId = + filterState.ids.dataset !== null + ? parseInt(filterState.ids.dataset) + : undefined + if (Number.isInteger(datasetId)) { + where.id = { + _eq: datasetId, + } + } + const empiarId = filterState.ids.empiar + const emdbId = filterState.ids.emdb + if (empiarId && emdbId) { + where.relatedDatabaseEntries = { + _regex: `(EMPIAR-${empiarId}.*EMD-${emdbId})|(EMD-${emdbId}.*EMPIAR-${empiarId})`, // Ignores order + } + } else if (empiarId) { + where.relatedDatabaseEntries = { + _regex: `EMPIAR-${empiarId}`, + } + } else if (emdbId) { + where.relatedDatabaseEntries = { + _regex: `EMD-${emdbId}`, + } + } + // Dataset Author + if (filterState.author.name) { + where.authors ??= {} + where.authors.name = { + _ilike: `%${filterState.author.name}%`, + } + } + if (filterState.author.orcid) { + where.authors ??= {} + where.authors.orcid = { + _ilike: `%${filterState.author.orcid}%`, + } + } + // Deposition ID + const filterDepositionId = + filterState.ids.deposition !== null + ? parseInt(filterState.ids.deposition) + : undefined + if (depositionId !== undefined || Number.isInteger(filterDepositionId)) { + where.runs ??= { annotations: {} } + where.runs.annotations ??= {} + where.runs.annotations.depositionId = { + _eq: depositionId ?? filterDepositionId, + } + } + + // SAMPLE AND EXPERIMENT CONDITIONS SECTION + const { organismNames } = filterState.sampleAndExperimentConditions + if (organismNames.length > 0) { + where.organismName = { + _in: organismNames, + } + } + + // ANNOTATION METADATA SECTION + const { objectNames, objectId, objectShapeTypes } = filterState.annotation + // Object Name + if (objectNames.length > 0) { + where.runs ??= { annotations: {} } + where.runs.annotations ??= {} + where.runs.annotations.objectName = { + _in: objectNames, + } + } + // Object ID + if (objectId) { + where.runs ??= { annotations: {} } + where.runs.annotations ??= {} + where.runs.annotations.objectId = { + _eq: objectId, + } + } + // Object Shape Type + if (objectShapeTypes.length > 0) { + where.runs ??= { annotations: {} } + where.runs.annotations ??= {} + where.runs.annotations.annotationShapes = { + shapeType: { + _in: objectShapeTypes as Annotation_File_Shape_Type_Enum[], // TODO(bchu): Remove typecast. + }, + } + } + + // HARDWARE SECTION + if (filterState.hardware.cameraManufacturer) { + where.runs ??= { tiltseries: {} } + where.runs.tiltseries ??= {} + where.runs.tiltseries.cameraManufacturer = { + _eq: filterState.hardware.cameraManufacturer, + } + } + + // TILT SERIES METADATA SECTION + const tiltRangeMin = parseFloat(filterState.tiltSeries.min) + const tiltRangeMax = parseFloat(filterState.tiltSeries.max) + if (Number.isFinite(tiltRangeMin) || Number.isFinite(tiltRangeMax)) { + where.runs ??= { tiltseries: {} } + where.runs.tiltseries ??= {} + where.runs.tiltseries.tiltRange = { + _gte: Number.isFinite(tiltRangeMin) + ? tiltRangeMin + : DEFAULT_TILT_RANGE_MIN, + _lte: Number.isFinite(tiltRangeMax) + ? tiltRangeMax + : DEFAULT_TILT_RANGE_MAX, + } + } + + // TOMOGRAM METADATA SECTION + // Fiducial Alignment Status + if (filterState.tomogram.fiducialAlignmentStatus) { + where.runs ??= { tomograms: {} } + where.runs.tomograms ??= {} + where.runs.tomograms.fiducialAlignmentStatus = { + _eq: + filterState.tomogram.fiducialAlignmentStatus === 'true' + ? Fiducial_Alignment_Status_Enum.Fiducial + : Fiducial_Alignment_Status_Enum.NonFiducial, + } + } + // Reconstruction Method + if (filterState.tomogram.reconstructionMethod) { + where.runs ??= { tomograms: {} } + where.runs.tomograms ??= {} + where.runs.tomograms.reconstructionMethod = { + _eq: convertReconstructionMethodToV2( + filterState.tomogram.reconstructionMethod, + ), + } + } + // Reconstruction Software + if (filterState.tomogram.reconstructionSoftware) { + where.runs ??= { tomograms: {} } + where.runs.tomograms ??= {} + where.runs.tomograms.reconstructionSoftware = { + _eq: filterState.tomogram.reconstructionSoftware, + } + } + + return where +} diff --git a/frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts b/frontend/packages/data-portal/app/graphql/fragments/getDatasetsAggregatesV2.server.ts similarity index 83% rename from frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts rename to frontend/packages/data-portal/app/graphql/fragments/getDatasetsAggregatesV2.server.ts index 233bf6e94..5eb5872d6 100644 --- a/frontend/packages/data-portal/app/graphql/fragments/getDatasetsFilterValuesV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/fragments/getDatasetsAggregatesV2.server.ts @@ -4,12 +4,12 @@ import { gql } from 'app/__generated_v2__' * Shares aggregate queries between datasets and deposition pages (the 2 pages are very similar). * * Parent query must define the following variables: - * - $datasetsFilter - * - $datasetsByDepositionFilter - * - $tiltseriesByDepositionFilter - * - $tomogramsByDepositionFilter - * - $annotationsByDepositionFilter - * - $annotationShapesByDepositionFilter + * - $datasetsFilter: DatasetWhereClause + * - $datasetsByDepositionFilter: DatasetWhereClause + * - $tiltseriesByDepositionFilter: TiltseriesWhereClause + * - $tomogramsByDepositionFilter: TomogramWhereClause + * - $annotationsByDepositionFilter: AnnotationWhereClause + * - $annotationShapesByDepositionFilter: AnnotationShapeWhereClause */ export const GET_DATASETS_AGGREGATES_FRAGMENT = gql(` fragment DatasetsAggregates on Query { diff --git a/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts index 1cbeafcb2..9e72c7f25 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetsV2.server.ts @@ -5,21 +5,11 @@ import type { } from '@apollo/client' import { gql } from 'app/__generated_v2__' -import { - Annotation_File_Shape_Type_Enum, - DatasetWhereClause, - Fiducial_Alignment_Status_Enum, - GetDatasetsV2Query, - OrderBy, -} from 'app/__generated_v2__/graphql' +import { GetDatasetsV2Query, OrderBy } from 'app/__generated_v2__/graphql' import { MAX_PER_PAGE } from 'app/constants/pagination' -import { - DEFAULT_TILT_RANGE_MAX, - DEFAULT_TILT_RANGE_MIN, -} from 'app/constants/tiltSeries' -import { FilterState, getFilterState } from 'app/hooks/useFilter' +import { getFilterState } from 'app/hooks/useFilter' -import { convertReconstructionMethodToV2 } from './common' +import { getDatasetsFilter } from './common' const GET_DATASETS_QUERY = gql(` query GetDatasetsV2( @@ -78,243 +68,6 @@ const GET_DATASETS_QUERY = gql(` } `) -function getFilter( - filterState: FilterState, - searchText?: string, -): DatasetWhereClause { - const where: DatasetWhereClause = {} - - // Search by Dataset Name - if (searchText) { - where.title = { - _ilike: `%${searchText}%`, - } - } - - // INCLUDED CONTENTS SECTION - // Ground Truth Annotation - if (filterState.includedContents.isGroundTruthEnabled) { - where.runs ??= { annotations: {} } - where.runs.annotations ??= {} - where.runs.annotations.groundTruthStatus = { - _eq: true, - } - } - // Available Files - // TODO(bchu): Implement when available in API. - // filterState.includedContents.availableFiles.forEach((file) => - // match(file) - // .with('raw-frames', () => - // where.push({ - // runs: { - // tiltseries: { - // frames_count: { - // _gt: 0, - // }, - // }, - // }, - // }), - // ) - // .with('tilt-series', () => - // where.push({ - // runs: { - // tiltseries_aggregate: { - // count: { - // predicate: { - // _gt: 0, - // }, - // }, - // }, - // }, - // }), - // ) - // .with('tilt-series-alignment', () => - // where.push({ - // runs: { - // tiltseries: { - // https_alignment_file: { - // _is_null: false, - // }, - // }, - // }, - // }), - // ) - // .with('tomogram', () => - // where.push({ - // runs: { - // tomogram_voxel_spacings: { - // tomograms_aggregate: { - // count: { - // predicate: { - // _gt: 0, - // }, - // }, - // }, - // }, - // }, - // }), - // ) - // .exhaustive(), - // ) - // Number of Runs - // TODO: Implement when available in API. - // if (filterState.includedContents.numberOfRuns) { - // const runCount = +filterState.includedContents.numberOfRuns.slice(1) - // where.push({ - // runs_aggregate: { - // count: { - // predicate: { _gte: runCount }, - // }, - // }, - // }) - // } - - // NAME/ID SECTION - // Dataset IDs - const datasetId = - filterState.ids.dataset !== null - ? parseInt(filterState.ids.dataset) - : undefined - if (Number.isInteger(datasetId)) { - where.id = { - _eq: datasetId, - } - } - const empiarId = filterState.ids.empiar - const emdbId = filterState.ids.emdb - if (empiarId && emdbId) { - where.relatedDatabaseEntries = { - _regex: `(EMPIAR-${empiarId}.*EMD-${emdbId})|(EMD-${emdbId}.*EMPIAR-${empiarId})`, // Ignores order - } - } else if (empiarId) { - where.relatedDatabaseEntries = { - _regex: `EMPIAR-${empiarId}`, - } - } else if (emdbId) { - where.relatedDatabaseEntries = { - _regex: `EMD-${emdbId}`, - } - } - // Dataset Author - if (filterState.author.name) { - where.authors ??= {} - where.authors.name = { - _ilike: `%${filterState.author.name}%`, - } - } - if (filterState.author.orcid) { - where.authors ??= {} - where.authors.orcid = { - _ilike: `%${filterState.author.orcid}%`, - } - } - // Deposition ID - const depositionId = - filterState.ids.deposition !== null - ? parseInt(filterState.ids.deposition) - : undefined - if (Number.isInteger(depositionId)) { - where.depositionId = { - _eq: depositionId, - } - } - - // SAMPLE AND EXPERIMENT CONDITIONS SECTION - const { organismNames } = filterState.sampleAndExperimentConditions - if (organismNames.length > 0) { - where.organismName = { - _in: organismNames, - } - } - - // ANNOTATION METADATA SECTION - const { objectNames, objectId, objectShapeTypes } = filterState.annotation - // Object Name - if (objectNames.length > 0) { - where.runs ??= { annotations: {} } - where.runs.annotations ??= {} - where.runs.annotations.objectName = { - _in: objectNames, - } - } - // Object ID - if (objectId) { - where.runs ??= { annotations: {} } - where.runs.annotations ??= {} - where.runs.annotations.objectId = { - _eq: objectId, - } - } - // Object Shape Type - if (objectShapeTypes.length > 0) { - where.runs ??= { annotations: {} } - where.runs.annotations ??= {} - where.runs.annotations.annotationShapes = { - shapeType: { - _in: objectShapeTypes as Annotation_File_Shape_Type_Enum[], // TODO(bchu): Remove typecast. - }, - } - } - - // HARDWARE SECTION - if (filterState.hardware.cameraManufacturer) { - where.runs ??= { tiltseries: {} } - where.runs.tiltseries ??= {} - where.runs.tiltseries.cameraManufacturer = { - _eq: filterState.hardware.cameraManufacturer, - } - } - - // TILT SERIES METADATA SECTION - const tiltRangeMin = parseFloat(filterState.tiltSeries.min) - const tiltRangeMax = parseFloat(filterState.tiltSeries.max) - if (Number.isFinite(tiltRangeMin) || Number.isFinite(tiltRangeMax)) { - where.runs ??= { tiltseries: {} } - where.runs.tiltseries ??= {} - where.runs.tiltseries.tiltRange = { - _gte: Number.isFinite(tiltRangeMin) - ? tiltRangeMin - : DEFAULT_TILT_RANGE_MIN, - _lte: Number.isFinite(tiltRangeMax) - ? tiltRangeMax - : DEFAULT_TILT_RANGE_MAX, - } - } - - // TOMOGRAM METADATA SECTION - // Fiducial Alignment Status - if (filterState.tomogram.fiducialAlignmentStatus) { - where.runs ??= { tomograms: {} } - where.runs.tomograms ??= {} - where.runs.tomograms.fiducialAlignmentStatus = { - _eq: - filterState.tomogram.fiducialAlignmentStatus === 'true' - ? Fiducial_Alignment_Status_Enum.Fiducial - : Fiducial_Alignment_Status_Enum.NonFiducial, - } - } - // Reconstruction Method - if (filterState.tomogram.reconstructionMethod) { - where.runs ??= { tomograms: {} } - where.runs.tomograms ??= {} - where.runs.tomograms.reconstructionMethod = { - _eq: convertReconstructionMethodToV2( - filterState.tomogram.reconstructionMethod, - ), - } - } - // Reconstruction Software - if (filterState.tomogram.reconstructionSoftware) { - where.runs ??= { tomograms: {} } - where.runs.tomograms ??= {} - where.runs.tomograms.reconstructionSoftware = { - _eq: filterState.tomogram.reconstructionSoftware, - } - } - - return where -} - export async function getDatasetsV2({ page, titleOrderDirection, @@ -331,7 +84,10 @@ export async function getDatasetsV2({ return client.query({ query: GET_DATASETS_QUERY, variables: { - datasetsFilter: getFilter(getFilterState(params), searchText), + datasetsFilter: getDatasetsFilter({ + filterState: getFilterState(params), + searchText, + }), limit: MAX_PER_PAGE, offset: (page - 1) * MAX_PER_PAGE, // Default order primarily by release date. diff --git a/frontend/packages/data-portal/app/graphql/getDepositionById.server.ts b/frontend/packages/data-portal/app/graphql/getDepositionById.server.ts index 828ce854c..77e05392c 100644 --- a/frontend/packages/data-portal/app/graphql/getDepositionById.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDepositionById.server.ts @@ -1,8 +1,16 @@ -import type { ApolloClient, NormalizedCacheObject } from '@apollo/client' +import type { + ApolloClient, + ApolloQueryResult, + NormalizedCacheObject, +} from '@apollo/client' import { match } from 'ts-pattern' import { gql } from 'app/__generated__' -import { Datasets_Bool_Exp, Order_By } from 'app/__generated__/graphql' +import { + Datasets_Bool_Exp, + GetDepositionByIdQuery, + Order_By, +} from 'app/__generated__/graphql' import { MAX_PER_PAGE } from 'app/constants/pagination' import { FilterState, getFilterState } from 'app/hooks/useFilter' import { getTiltRangeFilter } from 'app/utils/filter' @@ -106,7 +114,7 @@ const GET_DEPOSITION_BY_ID = gql(` runs { tomogram_voxel_spacings { - annotations(distinct_on: object_name) { + annotations(distinct_on: object_name, where: { deposition_id: { _eq: $id }}) { object_name } @@ -419,7 +427,7 @@ export async function getDepositionById({ id: number page?: number params?: URLSearchParams -}) { +}): Promise> { return client.query({ query: GET_DEPOSITION_BY_ID, variables: { diff --git a/frontend/packages/data-portal/app/graphql/getDepositionByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getDepositionByIdV2.server.ts new file mode 100644 index 000000000..73dba1d22 --- /dev/null +++ b/frontend/packages/data-portal/app/graphql/getDepositionByIdV2.server.ts @@ -0,0 +1,185 @@ +import type { + ApolloClient, + ApolloQueryResult, + NormalizedCacheObject, +} from '@apollo/client' + +import { gql } from 'app/__generated_v2__' +import { GetDepositionByIdV2Query, OrderBy } from 'app/__generated_v2__/graphql' +import { MAX_PER_PAGE } from 'app/constants/pagination' +import { getFilterState } from 'app/hooks/useFilter' + +import { getDatasetsFilter } from './common' + +const GET_DEPOSITION_BY_ID = gql(` + query GetDepositionByIdV2( + $id: Int!, + $datasetsLimit: Int!, + $datasetsOffset: Int!, + $datasetsOrderBy: [DatasetOrderByClause!], + $datasetsFilter: DatasetWhereClause!, + $datasetsByDepositionFilter: DatasetWhereClause!, + $tiltseriesByDepositionFilter: TiltseriesWhereClause!, + $tomogramsByDepositionFilter: TomogramWhereClause!, + $annotationsByDepositionFilter: AnnotationWhereClause!, + $annotationShapesByDepositionFilter: AnnotationShapeWhereClause! + ) { + # Deposition: + depositions(where: { id: { _eq: $id }}) { + depositionDate + depositionPublications + description + id + keyPhotoUrl + lastModifiedDate + relatedDatabaseEntries + releaseDate + title + authors(orderBy: { authorListOrder: asc }) { + edges { + node { + correspondingAuthorStatus + email + name + orcid + primaryAuthorStatus + } + } + } + annotationsAggregate { + aggregate { + count + } + } + distinctOrganismNames: datasetsAggregate { + aggregate { + count + groupBy { + organismName + } + } + } + distinctObjectNames: annotationsAggregate { + aggregate { + count + groupBy { + objectName + } + } + } + distinctShapeTypes: annotationsAggregate { + aggregate { + count + groupBy { + annotationShapes { + shapeType + } + } + } + } + annotationMethodCounts: annotationsAggregate { + aggregate { + count + groupBy { + annotationMethod + annotationSoftware + methodType + methodLinks { + link + linkType + name + } + } + } + } + } + + # Datasets: + # This section is very similar to the datasets page. + datasets( + where: $datasetsFilter + orderBy: $datasetsOrderBy, + limitOffset: { + limit: $datasetsLimit, + offset: $datasetsOffset + } + ) { + id + title + organismName + datasetPublications + keyPhotoThumbnailUrl + authors(orderBy: { authorListOrder: asc }) { + edges { + node { + name + primaryAuthorStatus + correspondingAuthorStatus + } + } + } + runsCount: runsAggregate(where: { annotations: $annotationsByDepositionFilter }) { + aggregate { + count + } + } + runs { + edges { + node { + annotationsAggregate(where: $annotationsByDepositionFilter) { + aggregate { + count + groupBy { + objectName + } + } + } + } + } + } + } + + ...DatasetsAggregates + } +`) + +export async function getDepositionByIdV2({ + client, + id, + orderBy, + page, + params, +}: { + client: ApolloClient + orderBy?: OrderBy + id: number + page: number + params: URLSearchParams +}): Promise> { + const depositionIdFilter = { + depositionId: { + _eq: id, + }, + } + + return client.query({ + query: GET_DEPOSITION_BY_ID, + variables: { + id, + datasetsLimit: MAX_PER_PAGE, + datasetsOffset: (page - 1) * MAX_PER_PAGE, + datasetsOrderBy: orderBy !== undefined ? [{ title: orderBy }] : undefined, + datasetsFilter: getDatasetsFilter({ + filterState: getFilterState(params), + depositionId: id, + }), + datasetsByDepositionFilter: depositionIdFilter, + tiltseriesByDepositionFilter: depositionIdFilter, + tomogramsByDepositionFilter: depositionIdFilter, + annotationsByDepositionFilter: depositionIdFilter, + annotationShapesByDepositionFilter: { + annotation: depositionIdFilter, + }, + }, + }) +} diff --git a/frontend/packages/data-portal/app/hooks/useDepositionById.ts b/frontend/packages/data-portal/app/hooks/useDepositionById.ts index 4340d588e..0bcd63169 100644 --- a/frontend/packages/data-portal/app/hooks/useDepositionById.ts +++ b/frontend/packages/data-portal/app/hooks/useDepositionById.ts @@ -8,8 +8,8 @@ export type Deposition = NonNullable export type Dataset = GetDepositionByIdQuery['datasets'][number] export function useDepositionById() { - const { depositionData: data, annotationMethodCounts } = useTypedLoaderData<{ - depositionData: GetDepositionByIdQuery + const { v1, annotationMethodCounts } = useTypedLoaderData<{ + v1: GetDepositionByIdQuery annotationMethodCounts: Map }>() @@ -17,40 +17,39 @@ export function useDepositionById() { () => Array.from( new Set( - data.deposition?.object_names.flatMap( + v1.deposition?.object_names.flatMap( (annotation) => annotation.object_name, ), ), ), - [data.deposition?.object_names], + [v1.deposition?.object_names], ) const objectShapeTypes = useMemo( () => Array.from( new Set( - data.deposition?.annotations.flatMap((annotation) => + v1.deposition?.annotations.flatMap((annotation) => annotation.files.flatMap((file) => file.shape_type), ), ), ), - [data.deposition?.annotations], + [v1.deposition?.annotations], ) const organismNames = useMemo( () => Array.from( - new Set(data.datasets.flatMap((dataset) => dataset.organism_name)), + new Set(v1.datasets.flatMap((dataset) => dataset.organism_name)), ).filter(Boolean) as string[], - [data.datasets], + [v1.datasets], ) return { - deposition: data.deposition as Deposition, - datasets: data.datasets, - datasetsCount: data.datasets_aggregate.aggregate?.count ?? 0, - filteredDatasetsCount: - data.filtered_datasets_aggregate.aggregate?.count ?? 0, + deposition: v1.deposition as Deposition, + datasets: v1.datasets, + datasetsCount: v1.datasets_aggregate.aggregate?.count ?? 0, + filteredDatasetsCount: v1.filtered_datasets_aggregate.aggregate?.count ?? 0, objectNames, objectShapeTypes, organismNames, diff --git a/frontend/packages/data-portal/app/routes/depositions.$id.tsx b/frontend/packages/data-portal/app/routes/depositions.$id.tsx index fbe0976ba..ab36f3821 100644 --- a/frontend/packages/data-portal/app/routes/depositions.$id.tsx +++ b/frontend/packages/data-portal/app/routes/depositions.$id.tsx @@ -7,7 +7,8 @@ import { useEffect } from 'react' import { typedjson } from 'remix-typedjson' import { Order_By } from 'app/__generated__/graphql' -import { apolloClient } from 'app/apollo.server' +import { OrderBy } from 'app/__generated_v2__/graphql' +import { apolloClient, apolloClientV2 } from 'app/apollo.server' import { DatasetFilter } from 'app/components/DatasetFilter' import { DepositionMetadataDrawer } from 'app/components/Deposition' import { DatasetsTable } from 'app/components/Deposition/DatasetsTable' @@ -19,6 +20,7 @@ import { QueryParams } from 'app/constants/query' import { getAnnotationCountForAnnotationMethod } from 'app/graphql/getAnnotationCountForAnnotationMethod' import { getDatasetsFilterData } from 'app/graphql/getDatasetsFilterData.server' import { getDepositionById } from 'app/graphql/getDepositionById.server' +import { getDepositionByIdV2 } from 'app/graphql/getDepositionByIdV2.server' import { useDepositionById } from 'app/hooks/useDepositionById' import { useI18n } from 'app/hooks/useI18n' import { @@ -55,12 +57,18 @@ export async function loader({ params, request }: LoaderFunctionArgs) { } let orderBy: Order_By | null = null + let orderByV2: OrderBy | undefined if (sort) { orderBy = sort === 'asc' ? Order_By.Asc : Order_By.Desc + orderByV2 = sort === 'asc' ? OrderBy.Asc : OrderBy.Desc } - const [depositionResponse, datasetsFilterReponse] = await Promise.all([ + const [ + { data: responseV1 }, + { data: datasetsFilterReponse }, + { data: responseV2 }, + ] = await Promise.all([ getDepositionById({ id, orderBy, @@ -72,18 +80,23 @@ export async function loader({ params, request }: LoaderFunctionArgs) { client: apolloClient, depositionId: id, }), + getDepositionByIdV2({ + client: apolloClientV2, + id, + orderBy: orderByV2, + page, + params: url.searchParams, + }), ]) - if (depositionResponse.data.deposition === null) { + if (responseV1.deposition == null) { throw new Response(null, { status: 404, statusText: `Deposition with ID ${id} not found`, }) } - const deposition = depositionResponse.data.deposition as NonNullable< - typeof depositionResponse.data.deposition - > + const { deposition } = responseV1 const annotationMethodCounts = new Map( await Promise.all( @@ -104,9 +117,10 @@ export async function loader({ params, request }: LoaderFunctionArgs) { ) return typedjson({ - depositionData: depositionResponse.data, - v1FilterValues: datasetsFilterReponse.data, + v1: responseV1, + v1FilterValues: datasetsFilterReponse, annotationMethodCounts, + v2: responseV2, }) } @@ -132,6 +146,7 @@ export function shouldRevalidate(args: ShouldRevalidateFunctionArgs) { QueryParams.ObjectName, QueryParams.ObjectId, QueryParams.ObjectShapeType, + QueryParams.Sort, ], }) } From d873866cdb478de0d8c5682fd5534535f3b2d40b Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:29:07 -0800 Subject: [PATCH 35/35] feat: Update ML Challenge banner (#1457) * test * clear mocks * try again * home * relaly --- .../MLChallenge/MLChallengeBanner.test.tsx | 52 ++++++---------- .../MLChallenge/MLChallengeBanner.tsx | 62 +++++-------------- .../data-portal/app/constants/localStorage.ts | 4 +- .../public/locales/en/translation.json | 3 +- 4 files changed, 39 insertions(+), 82 deletions(-) diff --git a/frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.test.tsx b/frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.test.tsx index da82df497..4dd8e1cc0 100644 --- a/frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.test.tsx +++ b/frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.test.tsx @@ -2,9 +2,8 @@ import { beforeEach, jest } from '@jest/globals' import { render, screen } from '@testing-library/react' import { MockI18n } from 'app/components/I18n.mock' -import { LocalStorageMock } from 'app/mocks/LocalStorage.mock' import { RemixMock } from 'app/mocks/Remix.mock' -import { getMockUser, setMockTime } from 'app/utils/mock' +import { getMockUser } from 'app/utils/mock' async function renderMlChallengeBanner() { const { MLChallengeBanner } = await import('./MLChallengeBanner') @@ -14,12 +13,10 @@ async function renderMlChallengeBanner() { jest.unstable_mockModule('app/components/I18n', () => ({ I18n: MockI18n })) const remixMock = new RemixMock() -const localStorageMock = new LocalStorageMock() describe('', () => { beforeEach(() => { - jest.useRealTimers() - localStorageMock.reset() + jest.clearAllMocks() remixMock.reset() }) @@ -28,63 +25,52 @@ describe('', () => { paths.forEach((pathname) => { it(`should render on ${pathname}`, async () => { remixMock.mockPathname(pathname) + await renderMlChallengeBanner() + expect(screen.queryByRole('banner')).toBeVisible() }) }) it('should not render on blocked pages', async () => { remixMock.mockPathname('/competition') - await renderMlChallengeBanner() - expect(screen.queryByRole('banner')).not.toBeInTheDocument() - }) - - it('should render challenge began message', async () => { - setMockTime('2024-12-01') await renderMlChallengeBanner() - expect(screen.getByText('mlCompetitionHasBegun')).toBeVisible() + + expect(screen.queryByRole('banner')).not.toBeInTheDocument() }) it('should render challenge ending message', async () => { - setMockTime('2025-01-30') + remixMock.mockPathname('/') await renderMlChallengeBanner() - expect(screen.getByText('mlCompetitionEnding')).toBeVisible() - }) - it('should render challenge ended message', async () => { - setMockTime('2025-02-07') - - await renderMlChallengeBanner() - expect(screen.getByText('mlCompetitionEnded')).toBeVisible() + expect(screen.getByText('mlCompetitionIsClosingSoon')).toBeVisible() }) it('should not render banner if was dismissed', async () => { - setMockTime('2024-12-01') - localStorageMock.mockValue('mlCompetitionHasBegun') + remixMock.mockPathname('/') + jest.spyOn(Storage.prototype, 'getItem').mockReturnValue('true') await renderMlChallengeBanner() + expect(screen.queryByRole('banner')).not.toBeInTheDocument() }) - it('should render banner if last dismissed was previous state', async () => { - setMockTime('2025-01-30') - localStorageMock.mockValue('mlCompetitionHasBegun') - + it('should dismiss banner on click', async () => { + jest.spyOn(Storage.prototype, 'getItem').mockReturnValue(null) + jest.spyOn(Storage.prototype, 'setItem') + remixMock.mockPathname('/') await renderMlChallengeBanner() - expect(screen.getByRole('banner')).toBeVisible() - }) - it('should dismiss banner on click', async () => { - setMockTime('2024-12-01') + expect(screen.queryByRole('banner')).toBeVisible() - await renderMlChallengeBanner() await getMockUser().click(screen.getByRole('button')) expect(screen.queryByRole('banner')).not.toBeInTheDocument() - expect(localStorageMock.setValue).toHaveBeenCalledWith( - 'mlCompetitionHasBegun', + expect(localStorage.setItem).toHaveBeenCalledWith( + 'competition-ending-banner-dismissed', + 'true', ) }) }) diff --git a/frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.tsx b/frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.tsx index 3dda725ac..cc545464e 100644 --- a/frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.tsx +++ b/frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.tsx @@ -1,75 +1,45 @@ import { Banner } from '@czi-sds/components' -import { useLocalStorageValue } from '@react-hookz/web' import { useLocation } from '@remix-run/react' -import dayjs from 'dayjs' import { useState } from 'react' -import { match, P } from 'ts-pattern' -import { I18n } from 'app/components/I18n' import { LocalStorageKeys } from 'app/constants/localStorage' import { useEffectOnce } from 'app/hooks/useEffectOnce' -import { I18nKeys } from 'app/types/i18n' -const BANNER_ALLOWLIST = [/^\/$/, /^\/browse-data\/.*$/] -const ML_CHALLENGE_END_DATE = dayjs('February 6, 2025') +import { I18n } from '../I18n' -// TODO(jeremy) check with team to see what the correct interval is -const ML_CHALLENGE_END_INTERVAL = 10 - -const ML_CHALLENGE_END_NOTIFY_DATE = ML_CHALLENGE_END_DATE.subtract( - ML_CHALLENGE_END_INTERVAL, - 'days', -) +const BANNER_PATHS = [/^\/$/, /^\/browse-data\/.*$/] export function MLChallengeBanner() { - const { - value: lastDismissedBannerMessage, - set: setLastDismissedBannerMessage, - } = useLocalStorageValue( - LocalStorageKeys.CompetitionBannerDismissed, - { defaultValue: null }, - ) - const [open, setOpen] = useState(false) const location = useLocation() - - const now = dayjs() - - const bannerI18nKey = match(now) - .with( - P.when((d) => d.isAfter(ML_CHALLENGE_END_DATE)), - () => 'mlCompetitionEnded' as I18nKeys, - ) - .with( - P.when((d) => d.isAfter(ML_CHALLENGE_END_NOTIFY_DATE)), - () => 'mlCompetitionEnding' as I18nKeys, - ) - .otherwise(() => 'mlCompetitionHasBegun' as I18nKeys) + const [open, setOpen] = useState(false) // open banner on client side to prevent flash of content since local storage // is not available when server-side rendering. - useEffectOnce(() => setOpen(bannerI18nKey !== lastDismissedBannerMessage)) + useEffectOnce(() => + setOpen( + localStorage.getItem( + LocalStorageKeys.CompetitionEndingBannerDismissed, + ) !== 'true', + ), + ) return ( !regex.test(location.pathname)) + !open || BANNER_PATHS.every((regex) => !regex.test(location.pathname)) } dismissible sdsType="primary" onClose={() => { setOpen(false) - setLastDismissedBannerMessage(bannerI18nKey) + localStorage.setItem( + LocalStorageKeys.CompetitionEndingBannerDismissed, + 'true', + ) }} >
- +
) diff --git a/frontend/packages/data-portal/app/constants/localStorage.ts b/frontend/packages/data-portal/app/constants/localStorage.ts index 70d9ec8a3..435f5e343 100644 --- a/frontend/packages/data-portal/app/constants/localStorage.ts +++ b/frontend/packages/data-portal/app/constants/localStorage.ts @@ -1,5 +1,7 @@ export enum LocalStorageKeys { - CompetitionBannerDismissed = 'competition-banner-dismissed', + CompetitionEndingBannerDismissed = 'competition-ending-banner-dismissed', SurveyBannerDismissed = 'survey-banner-dismissed', TableRenderErrorPageReloadCount = 'table-render-error-page-reload-count', + // DEPRECATED - DO NOT USE (keep these in the enum so we know not to use them in the future): + CompetitionBannerDismissed = 'competition-banner-dismissed', } diff --git a/frontend/packages/data-portal/public/locales/en/translation.json b/frontend/packages/data-portal/public/locales/en/translation.json index 5614b28d0..710065fe5 100644 --- a/frontend/packages/data-portal/public/locales/en/translation.json +++ b/frontend/packages/data-portal/public/locales/en/translation.json @@ -241,8 +241,7 @@ "microscopeModel": "Microscope model", "mlChallengeEndDate": "February 5, 2025", "mlChallengeStartDate": "November 6, 2024", - "mlCompetitionEnded": "Congratulations to the ML Competition winners! $t(mlCompetitionLearnMore) about the winning models.", - "mlCompetitionEnding": "ML Competition is ending in {{days}} days. Compete for cash prizes. $t(mlCompetitionLearnMore)", + "mlCompetitionIsClosingSoon": "ML Competition is closing soon. Enter by 1/29 for cash prizes. $t(mlCompetitionLearnMore)", "mlCompetitionHasBegun": "ML Competition has begun. Enter for cash prizes. $t(mlCompetitionLearnMore)", "mlCompetitionLearnMore": "Learn More", "modelWeights": "Model Weights",

-FiT#;{Ge==L8 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 z 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 Date: Tue, 17 Dec 2024 18:24:16 +0000 Subject: [PATCH 05/35] chore(main): release web 1.37.2 (#1402) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit :robot: I have created a release *beep* *boop* --- ## [1.37.2](https://github.com/chanzuckerberg/cryoet-data-portal/compare/web-v1.37.1...web-v1.37.2) (2024-12-17) ### 🧪 Tests * simple component unit tests ([#1392](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1392)) ([45e214e](https://github.com/chanzuckerberg/cryoet-data-portal/commit/45e214e1b02970edf795de5392709e0be23f959c)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- frontend/CHANGELOG.md | 7 +++++++ frontend/package.json | 2 +- release-please.manifest.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index a1340ba0a..04eda7522 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.37.2](https://github.com/chanzuckerberg/cryoet-data-portal/compare/web-v1.37.1...web-v1.37.2) (2024-12-17) + + +### 🧪 Tests + +* simple component unit tests ([#1392](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1392)) ([45e214e](https://github.com/chanzuckerberg/cryoet-data-portal/commit/45e214e1b02970edf795de5392709e0be23f959c)) + ## [1.37.1](https://github.com/chanzuckerberg/cryoet-data-portal/compare/web-v1.37.0...web-v1.37.1) (2024-12-11) diff --git a/frontend/package.json b/frontend/package.json index ceb16dc03..f65e9508e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "1.37.1", + "version": "1.37.2", "scripts": { "preinstall": "npx only-allow pnpm", "build": "pnpm -r build", diff --git a/release-please.manifest.json b/release-please.manifest.json index a23fec18b..9a2008ea2 100644 --- a/release-please.manifest.json +++ b/release-please.manifest.json @@ -1,4 +1,4 @@ { - "frontend": "1.37.1", + "frontend": "1.37.2", "client/python/cryoet_data_portal": "4.2.1" } From 639cd901ca4c0def4baa1bdd6e8bd1aeb011a46e Mon Sep 17 00:00:00 2001 From: Ronen Date: Wed, 18 Dec 2024 17:44:57 -0500 Subject: [PATCH 06/35] chore: update python matrix (#1407) - Updated test matrix - removed Python 3.7 and added 3.11 and 3.12 - Fixed `coverage` --- .github/workflows/client-python.yml | 33 ++++++++++++------- .../tests/test_infra/get_deployment.sh | 2 +- .../cryoet_data_portal_docsite_quick_start.md | 29 ++++++++-------- 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/.github/workflows/client-python.yml b/.github/workflows/client-python.yml index 57156b396..a05d32305 100644 --- a/.github/workflows/client-python.yml +++ b/.github/workflows/client-python.yml @@ -5,14 +5,14 @@ on: branches: - main paths: - - 'client/python/**' - - '.github/workflows/client-python.yml' + - "client/python/**" + - ".github/workflows/client-python.yml" pull_request: branches: - - '**' + - "**" paths: - - 'client/python/**' - - '.github/workflows/client-python.yml' + - "client/python/**" + - ".github/workflows/client-python.yml" jobs: test-client-python: @@ -22,7 +22,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: ['3.7', '3.8', '3.9', '3.10'] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - name: Checkout Repo @@ -46,11 +46,14 @@ jobs: make coverage - name: Upload Coverage - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: coverage + name: coverage-${{ matrix.os }}-${{ matrix.python-version }} path: ./client/python/cryoet_data_portal/.coverage* retention-days: 3 + include-hidden-files: true + - name: Verify Coverage Files + run: ls -la ./client/python/cryoet_data_portal submit-codecoverage: needs: @@ -63,15 +66,21 @@ jobs: fetch-depth: 0 - name: Download Coverage - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: coverage - path: . + path: ./coverage + + - name: Verify Coverage Artifacts + run: ls -R ./coverage + + - name: Move Coverage Files + run: | + find ./coverage -type f -name ".coverage*" -exec mv {} . \; - name: Setup Python uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: "3.12" - name: Install Requirements run: | diff --git a/client/python/cryoet_data_portal/tests/test_infra/get_deployment.sh b/client/python/cryoet_data_portal/tests/test_infra/get_deployment.sh index e815b17dc..7755c7b0f 100755 --- a/client/python/cryoet_data_portal/tests/test_infra/get_deployment.sh +++ b/client/python/cryoet_data_portal/tests/test_infra/get_deployment.sh @@ -7,5 +7,5 @@ if [ -n "$RELEASE_SHA" ]; then echo $RELEASE_SHA else # If this isn't staging, or we don't have an active release-please branch, fetch the appropriate hash from the `main` branch. - curl -s "https://raw.githubusercontent.com/chanzuckerberg/cryoet-data-portal-backend/refs/heads/main/.infra/$1/values.yaml" | grep ' tag:' | head -n 1 | awk '{ print $2; }' | cut -d '-' -f 2 + curl -s "https://api.github.com/repos/chanzuckerberg/cryoet-data-portal-backend/commits/main" | grep '"sha":' | head -n 1 | awk -F '"' '{ print $4 }' fi diff --git a/docs/cryoet_data_portal_docsite_quick_start.md b/docs/cryoet_data_portal_docsite_quick_start.md index e682be50f..5ebee8c58 100644 --- a/docs/cryoet_data_portal_docsite_quick_start.md +++ b/docs/cryoet_data_portal_docsite_quick_start.md @@ -3,6 +3,7 @@ hide-navigation: true --- (quick-start)= + # Quickstart This page provides details to help you get started using the CryoET Data Portal Client API. @@ -19,7 +20,7 @@ This page provides details to help you get started using the CryoET Data Portal The CryoET Data Portal Client requires a Linux or MacOS system with: -- Python 3.7 to Python 3.11. +- Python 3.8 to Python 3.12. - Recommended: >16 GB of memory. - Recommended: >5 Mbps internet connection. - Recommended: for increased performance, use the API through an AWS-EC2 instance from the region `us-west-2`. The CryoET Portal data are hosted in a AWS-S3 bucket in that region. @@ -43,22 +44,22 @@ pip install -U cryoet-data-portal The Portal API has methods for searching and downloading data. **Every class** has a `find` and `get_by_id` method for selecting data, and some classes have `download...` methods for downloading the data. Below is a table of the API classes that have download methods. -| **Class** | **Download Methods** | -|-------------------------|--------------------------------------------------------------------------------------------------------| -| {class}`Annotation `| `download`, `download_metadata` | -| {class}`Dataset `| `download_everything` | -| {class}`Run `| `download_everything` | -| {class}`TiltSeries `| `download_alignment_file`, `download_angle_list`, `download_mrcfile`, `download_omezarr` | -| {class}`Tomogram `| `download_all_annotations`, `download_mrcfile`, `download_omezarr` | -| {class}`TomogramVoxelSpacing `| `download_everything` | +| **Class** | **Download Methods** | +| ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| {class}`Annotation ` | `download`, `download_metadata` | +| {class}`Dataset ` | `download_everything` | +| {class}`Run ` | `download_everything` | +| {class}`TiltSeries ` | `download_alignment_file`, `download_angle_list`, `download_mrcfile`, `download_omezarr` | +| {class}`Tomogram ` | `download_all_annotations`, `download_mrcfile`, `download_omezarr` | +| {class}`TomogramVoxelSpacing ` | `download_everything` | The `find` method selects data based on user-chosen queries. These queries can have python operators `==`, `!=`, `>`, `>=`, `<`, `<=`; method operators `like`, `ilike`, `_in`; and strings or numbers. The method operators are defined in the table below: -| **Method Operator** | **Definition** | -|---------------------|----------------------------------------------------------------------------------------------| -| like | partial match, with the `%` character being a wildcard | -| ilike | case-insensitive partial match, with the `%` character being a wildcard | -| _in | accepts a list of values that are acceptable matches | +| **Method Operator** | **Definition** | +| ------------------- | ----------------------------------------------------------------------- | +| like | partial match, with the `%` character being a wildcard | +| ilike | case-insensitive partial match, with the `%` character being a wildcard | +| \_in | accepts a list of values that are acceptable matches | The general format of using the `find` method is as follows: From 71797529b5114157979683aef35abcab9d014903 Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:45:14 -0800 Subject: [PATCH 07/35] fix: Fix run query diff logging (#1405) Also update printed value to just be the actual objects (much easier to plug the 2 strings into an online JSON differ and see all the fields to get a sense of what's different). --- .../app/graphql/getRunById.server.ts | 11 ++++-- .../app/graphql/getRunByIdDiffer.ts | 37 ++++++++++++------- .../app/graphql/getRunByIdV2.server.ts | 1 + 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/frontend/packages/data-portal/app/graphql/getRunById.server.ts b/frontend/packages/data-portal/app/graphql/getRunById.server.ts index 05d16691d..200e9a231 100644 --- a/frontend/packages/data-portal/app/graphql/getRunById.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunById.server.ts @@ -93,9 +93,14 @@ const GET_RUN_BY_ID_QUERY = gql(` } funding_sources( - order_by: { - funding_agency_name: asc - } + order_by: [ + { + funding_agency_name: asc + }, + { + grant_id: asc + } + ] ) { funding_agency_name grant_id diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts index 28f412158..304a37e2c 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts @@ -23,23 +23,29 @@ export function logIfHasDiff( v2 = structuredClone(v2) // There are no alignments in V1. delete v2.alignmentsAggregate.aggregate - // Sort annotation files for consistency. for (const annotationShape of v2.annotationShapes) { + // There are no alignments in V1. + for (const annotationFile of annotationShape.annotationFiles.edges) { + delete annotationFile.node.alignmentId + } + // Sort annotation files for consistency. annotationShape.annotationFiles.edges.sort((edge) => edge.node.format.localeCompare(edge.node.format), ) } - // Tomogram deposition relations in V1 are incomplete. for (const tomogram of v2.tomograms) { - // There are no alignments in V1. + // Delete fields that don't exist in V1. delete tomogram.alignment - // Tomogram deposition relations in V1 are incomplete. + delete tomogram.isVisualizationDefault + delete tomogram.releaseDate + delete tomogram.lastModifiedDate + delete tomogram.relatedDatabaseEntries delete tomogram.deposition // Standard tomograms are V2 only. tomogram.isPortalStandard = false } - // Frames are not populated in V2 yet. for (const run of v2.runs) { + // There are no frames in V1. delete run.framesAggregate } @@ -98,7 +104,7 @@ export function logIfHasDiff( ? Number(run.dataset.organism_taxid) : run.dataset.organism_taxid, otherSetup: run.dataset.other_setup, - // publications: run.dataset.dataset_publications, + datasetPublications: run.dataset.dataset_publications, relatedDatabaseEntries: run.dataset.related_database_entries, releaseDate: `${run.dataset.release_date}T00:00:00+00:00`, s3Prefix: run.dataset.s3_prefix, @@ -156,7 +162,10 @@ export function logIfHasDiff( alignment: { affineTransformationMatrix: JSON.stringify( tomogram.affine_transformation_matrix, - ).replaceAll(',', ', '), + ) + .replaceAll('[', '{') + .replaceAll(']', '}') + .replaceAll(', ', ','), }, }, })), @@ -196,12 +205,12 @@ export function logIfHasDiff( annotationSoftware: file.annotation.annotation_software, confidencePrecision: file.annotation.confidence_precision, confidenceRecall: file.annotation.confidence_recall, - depositionDate: file.annotation.deposition_date, + depositionDate: `${file.annotation.deposition_date}T00:00:00+00:00`, groundTruthStatus: file.annotation.ground_truth_status, groundTruthUsed: file.annotation.ground_truth_used, id: file.annotation.id, isCuratorRecommended: file.annotation.is_curator_recommended, - lastModifiedDate: file.annotation.last_modified_date!, + lastModifiedDate: `${file.annotation.last_modified_date}T00:00:00+00:00`, methodLinks: { edges: [], }, @@ -211,11 +220,11 @@ export function logIfHasDiff( objectId: file.annotation.object_id, objectName: file.annotation.object_name, objectState: file.annotation.object_state, - releaseDate: file.annotation.release_date, + releaseDate: `${file.annotation.release_date}T00:00:00+00:00`, authors: { edges: file.annotation.authors.map((author) => ({ node: { - primaryAuthorStatus: author.primary_author_status, + primaryAuthorStatus: author.primary_author_status ?? false, correspondingAuthorStatus: author.corresponding_author_status, name: author.name, email: author.email, @@ -286,9 +295,9 @@ export function logIfHasDiff( if (Object.keys(diffObject).length > 0) { console.log( - `DIFF AT ${url}: ${JSON.stringify(diffObject)} --- ${JSON.stringify( - diff(v2, v1Transformed), - )}`, + `DIFF AT ${url} ========== ${JSON.stringify( + v1Transformed, + )} ========== ${JSON.stringify(v2)}`, ) } } diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts index 969eb3360..030b166dd 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts @@ -87,6 +87,7 @@ const GET_RUN_BY_ID_QUERY_V2 = gql(` fundingSources( orderBy: { fundingAgencyName: asc + grantId: asc } ) { edges { From 3b8e709a5d44be4085be54c780723fb6910fb521 Mon Sep 17 00:00:00 2001 From: Ronen Date: Thu, 19 Dec 2024 10:28:37 -0500 Subject: [PATCH 08/35] feat: add size fields to TiltSeries (#1406) Relates to: https://github.com/chanzuckerberg/cryoet-data-portal-backend/pull/387 --- .../src/cryoet_data_portal/_models.py | 6 + .../cryoet_data_portal/data/schema.graphql | 563 ++++++++++-------- 2 files changed, 325 insertions(+), 244 deletions(-) diff --git a/client/python/cryoet_data_portal/src/cryoet_data_portal/_models.py b/client/python/cryoet_data_portal/src/cryoet_data_portal/_models.py index 02c268240..7f5da108d 100644 --- a/client/python/cryoet_data_portal/src/cryoet_data_portal/_models.py +++ b/client/python/cryoet_data_portal/src/cryoet_data_portal/_models.py @@ -1362,6 +1362,9 @@ class TiltSeries(Model): is_aligned (bool): Whether this tilt series is aligned pixel_spacing (float): Pixel spacing equal in both axes in angstroms aligned_tiltseries_binning (int): Binning factor of the aligned tilt series + size_x (int): Number of pixels in the 3D data fast axis + size_y (int): Number of pixels in the 3D data medium axis + size_z (int): Number of pixels in the 3D data slow axis """ _gql_type: str = "Tiltseries" @@ -1403,6 +1406,9 @@ class TiltSeries(Model): is_aligned: bool = BooleanField() pixel_spacing: float = FloatField() aligned_tiltseries_binning: int = IntField() + size_x: int = IntField() + size_y: int = IntField() + size_z: int = IntField() @classmethod def find( diff --git a/client/python/cryoet_data_portal/src/cryoet_data_portal/data/schema.graphql b/client/python/cryoet_data_portal/src/cryoet_data_portal/data/schema.graphql index 22f23c00f..13ee70a6b 100644 --- a/client/python/cryoet_data_portal/src/cryoet_data_portal/data/schema.graphql +++ b/client/python/cryoet_data_portal/src/cryoet_data_portal/data/schema.graphql @@ -693,6 +693,9 @@ input TiltseriesWhereClause { isAligned: BoolComparators pixelSpacing: FloatComparators alignedTiltseriesBinning: IntComparators + sizeX: IntComparators + sizeY: IntComparators + sizeZ: IntComparators id: IntComparators } @@ -1167,6 +1170,9 @@ input TiltseriesOrderByClause { isAligned: orderBy pixelSpacing: orderBy alignedTiltseriesBinning: orderBy + sizeX: orderBy + sizeY: orderBy + sizeZ: orderBy id: orderBy } @@ -1456,12 +1462,16 @@ type AnnotationShapeMinMaxColumns { type AnnotationShapeGroupByOptions { annotation: AnnotationGroupByOptions + annotationFiles: AnnotationFileGroupByOptions shapeType: annotation_file_shape_type_enum id: Int } type AnnotationGroupByOptions { run: RunGroupByOptions + annotationShapes: AnnotationShapeGroupByOptions + methodLinks: AnnotationMethodLinkGroupByOptions + authors: AnnotationAuthorGroupByOptions deposition: DepositionGroupByOptions s3MetadataPath: String httpsMetadataPath: String @@ -1486,15 +1496,163 @@ type AnnotationGroupByOptions { } type RunGroupByOptions { + alignments: AlignmentGroupByOptions + annotations: AnnotationGroupByOptions dataset: DatasetGroupByOptions + frames: FrameGroupByOptions + gainFiles: GainFileGroupByOptions + frameAcquisitionFiles: FrameAcquisitionFileGroupByOptions + tiltseries: TiltseriesGroupByOptions + tomogramVoxelSpacings: TomogramVoxelSpacingGroupByOptions + tomograms: TomogramGroupByOptions name: String s3Prefix: String httpsPrefix: String id: Int } +type AlignmentGroupByOptions { + annotationFiles: AnnotationFileGroupByOptions + perSectionAlignments: PerSectionAlignmentParametersGroupByOptions + deposition: DepositionGroupByOptions + tiltseries: TiltseriesGroupByOptions + tomograms: TomogramGroupByOptions + run: RunGroupByOptions + alignmentType: alignment_type_enum + alignmentMethod: alignment_method_type_enum + volumeXDimension: Float + volumeYDimension: Float + volumeZDimension: Float + volumeXOffset: Float + volumeYOffset: Float + volumeZOffset: Float + xRotationOffset: Float + tiltOffset: Float + affineTransformationMatrix: String + s3AlignmentMetadata: String + httpsAlignmentMetadata: String + isPortalStandard: Boolean + id: Int +} + +type AnnotationFileGroupByOptions { + alignment: AlignmentGroupByOptions + annotationShape: AnnotationShapeGroupByOptions + tomogramVoxelSpacing: TomogramVoxelSpacingGroupByOptions + format: String + s3Path: String + httpsPath: String + isVisualizationDefault: Boolean + source: annotation_file_source_enum + id: Int +} + +type TomogramVoxelSpacingGroupByOptions { + annotationFiles: AnnotationFileGroupByOptions + run: RunGroupByOptions + tomograms: TomogramGroupByOptions + voxelSpacing: Float + s3Prefix: String + httpsPrefix: String + id: Int +} + +type TomogramGroupByOptions { + alignment: AlignmentGroupByOptions + authors: TomogramAuthorGroupByOptions + deposition: DepositionGroupByOptions + run: RunGroupByOptions + tomogramVoxelSpacing: TomogramVoxelSpacingGroupByOptions + name: String + sizeX: Int + sizeY: Int + sizeZ: Int + voxelSpacing: Float + fiducialAlignmentStatus: fiducial_alignment_status_enum + reconstructionMethod: tomogram_reconstruction_method_enum + processing: tomogram_processing_enum + tomogramVersion: Float + processingSoftware: String + reconstructionSoftware: String + isPortalStandard: Boolean + isAuthorSubmitted: Boolean + isVisualizationDefault: Boolean + s3OmezarrDir: String + httpsOmezarrDir: String + s3MrcFile: String + httpsMrcFile: String + scale0Dimensions: String + scale1Dimensions: String + scale2Dimensions: String + ctfCorrected: Boolean + offsetX: Int + offsetY: Int + offsetZ: Int + keyPhotoUrl: String + keyPhotoThumbnailUrl: String + neuroglancerConfig: String + publications: String + relatedDatabaseEntries: String + id: Int + depositionDate: DateTime + releaseDate: DateTime + lastModifiedDate: DateTime +} + +type TomogramAuthorGroupByOptions { + tomogram: TomogramGroupByOptions + id: Int + authorListOrder: Int + orcid: String + name: String + email: String + affiliationName: String + affiliationAddress: String + affiliationIdentifier: String + correspondingAuthorStatus: Boolean + primaryAuthorStatus: Boolean +} + +type DepositionGroupByOptions { + authors: DepositionAuthorGroupByOptions + alignments: AlignmentGroupByOptions + annotations: AnnotationGroupByOptions + datasets: DatasetGroupByOptions + frames: FrameGroupByOptions + tiltseries: TiltseriesGroupByOptions + tomograms: TomogramGroupByOptions + title: String + description: String + depositionTypes: DepositionTypeGroupByOptions + depositionPublications: String + relatedDatabaseEntries: String + depositionDate: DateTime + releaseDate: DateTime + lastModifiedDate: DateTime + keyPhotoUrl: String + keyPhotoThumbnailUrl: String + id: Int +} + +type DepositionAuthorGroupByOptions { + deposition: DepositionGroupByOptions + id: Int + authorListOrder: Int + orcid: String + name: String + email: String + affiliationName: String + affiliationAddress: String + affiliationIdentifier: String + correspondingAuthorStatus: Boolean + primaryAuthorStatus: Boolean +} + type DatasetGroupByOptions { deposition: DepositionGroupByOptions + fundingSources: DatasetFundingGroupByOptions + authors: DatasetAuthorGroupByOptions + runs: RunGroupByOptions title: String description: String organismName: String @@ -1523,19 +1681,132 @@ type DatasetGroupByOptions { id: Int } -type DepositionGroupByOptions { - title: String - description: String - depositionPublications: String - relatedDatabaseEntries: String - depositionDate: DateTime - releaseDate: DateTime - lastModifiedDate: DateTime - keyPhotoUrl: String - keyPhotoThumbnailUrl: String +type DatasetFundingGroupByOptions { + dataset: DatasetGroupByOptions + fundingAgencyName: String + grantId: String + id: Int +} + +type DatasetAuthorGroupByOptions { + dataset: DatasetGroupByOptions + id: Int + authorListOrder: Int + orcid: String + name: String + email: String + affiliationName: String + affiliationAddress: String + affiliationIdentifier: String + correspondingAuthorStatus: Boolean + primaryAuthorStatus: Boolean +} + +type FrameGroupByOptions { + deposition: DepositionGroupByOptions + run: RunGroupByOptions + rawAngle: Float + acquisitionOrder: Int + dose: Float + isGainCorrected: Boolean + s3FramePath: String + httpsFramePath: String id: Int } +type TiltseriesGroupByOptions { + alignments: AlignmentGroupByOptions + run: RunGroupByOptions + deposition: DepositionGroupByOptions + s3OmezarrDir: String + s3MrcFile: String + httpsOmezarrDir: String + httpsMrcFile: String + s3AngleList: String + httpsAngleList: String + accelerationVoltage: Int + sphericalAberrationConstant: Float + microscopeManufacturer: tiltseries_microscope_manufacturer_enum + microscopeModel: String + microscopeEnergyFilter: String + microscopePhasePlate: String + microscopeImageCorrector: String + microscopeAdditionalInfo: String + cameraManufacturer: String + cameraModel: String + tiltMin: Float + tiltMax: Float + tiltRange: Float + tiltStep: Float + tiltingScheme: String + tiltAxis: Float + totalFlux: Float + dataAcquisitionSoftware: String + relatedEmpiarEntry: String + binningFromFrames: Float + tiltSeriesQuality: Int + isAligned: Boolean + pixelSpacing: Float + alignedTiltseriesBinning: Int + sizeX: Int + sizeY: Int + sizeZ: Int + id: Int +} + +type DepositionTypeGroupByOptions { + deposition: DepositionGroupByOptions + type: deposition_types_enum + id: Int +} + +type PerSectionAlignmentParametersGroupByOptions { + alignment: AlignmentGroupByOptions + zIndex: Int + xOffset: Float + yOffset: Float + volumeXRotation: Float + inPlaneRotation: [[Float!]!] + tiltAngle: Float + id: Int +} + +type GainFileGroupByOptions { + run: RunGroupByOptions + s3FilePath: String + httpsFilePath: String + id: Int +} + +type FrameAcquisitionFileGroupByOptions { + run: RunGroupByOptions + s3MdocPath: String + httpsMdocPath: String + id: Int +} + +type AnnotationMethodLinkGroupByOptions { + annotation: AnnotationGroupByOptions + linkType: annotation_method_link_type_enum + name: String + link: String + id: Int +} + +type AnnotationAuthorGroupByOptions { + annotation: AnnotationGroupByOptions + id: Int + authorListOrder: Int + orcid: String + name: String + email: String + affiliationName: String + affiliationAddress: String + affiliationIdentifier: String + correspondingAuthorStatus: Boolean + primaryAuthorStatus: Boolean +} + enum AnnotationShapeCountColumns { annotation annotationFiles @@ -1606,19 +1877,11 @@ type AnnotationMethodLinkAggregateFunctions { count(distinct: Boolean = false, columns: AnnotationMethodLinkCountColumns = null): Int } -type AnnotationMethodLinkNumericalColumns { - id: Int -} - -type AnnotationMethodLinkMinMaxColumns { - name: String - link: String +type AnnotationMethodLinkNumericalColumns { id: Int } -type AnnotationMethodLinkGroupByOptions { - annotation: AnnotationGroupByOptions - linkType: annotation_method_link_type_enum +type AnnotationMethodLinkMinMaxColumns { name: String link: String id: Int @@ -1739,20 +2002,6 @@ type AnnotationAuthorMinMaxColumns { affiliationIdentifier: String } -type AnnotationAuthorGroupByOptions { - annotation: AnnotationGroupByOptions - id: Int - authorListOrder: Int - orcid: String - name: String - email: String - affiliationName: String - affiliationAddress: String - affiliationIdentifier: String - correspondingAuthorStatus: Boolean - primaryAuthorStatus: Boolean -} - enum AnnotationAuthorCountColumns { annotation id @@ -2042,20 +2291,6 @@ type DepositionAuthorMinMaxColumns { affiliationIdentifier: String } -type DepositionAuthorGroupByOptions { - deposition: DepositionGroupByOptions - id: Int - authorListOrder: Int - orcid: String - name: String - email: String - affiliationName: String - affiliationAddress: String - affiliationIdentifier: String - correspondingAuthorStatus: Boolean - primaryAuthorStatus: Boolean -} - enum DepositionAuthorCountColumns { deposition id @@ -2112,63 +2347,6 @@ type AlignmentMinMaxColumns { id: Int } -type AlignmentGroupByOptions { - deposition: DepositionGroupByOptions - tiltseries: TiltseriesGroupByOptions - run: RunGroupByOptions - alignmentType: alignment_type_enum - alignmentMethod: alignment_method_type_enum - volumeXDimension: Float - volumeYDimension: Float - volumeZDimension: Float - volumeXOffset: Float - volumeYOffset: Float - volumeZOffset: Float - xRotationOffset: Float - tiltOffset: Float - affineTransformationMatrix: String - s3AlignmentMetadata: String - httpsAlignmentMetadata: String - isPortalStandard: Boolean - id: Int -} - -type TiltseriesGroupByOptions { - run: RunGroupByOptions - deposition: DepositionGroupByOptions - s3OmezarrDir: String - s3MrcFile: String - httpsOmezarrDir: String - httpsMrcFile: String - s3AngleList: String - httpsAngleList: String - accelerationVoltage: Int - sphericalAberrationConstant: Float - microscopeManufacturer: tiltseries_microscope_manufacturer_enum - microscopeModel: String - microscopeEnergyFilter: String - microscopePhasePlate: String - microscopeImageCorrector: String - microscopeAdditionalInfo: String - cameraManufacturer: String - cameraModel: String - tiltMin: Float - tiltMax: Float - tiltRange: Float - tiltStep: Float - tiltingScheme: String - tiltAxis: Float - totalFlux: Float - dataAcquisitionSoftware: String - relatedEmpiarEntry: String - binningFromFrames: Float - tiltSeriesQuality: Int - isAligned: Boolean - pixelSpacing: Float - alignedTiltseriesBinning: Int - id: Int -} - enum AlignmentCountColumns { annotationFiles perSectionAlignments @@ -2523,13 +2701,6 @@ type DatasetFundingMinMaxColumns { id: Int } -type DatasetFundingGroupByOptions { - dataset: DatasetGroupByOptions - fundingAgencyName: String - grantId: String - id: Int -} - enum DatasetFundingCountColumns { dataset fundingAgencyName @@ -2642,20 +2813,6 @@ type DatasetAuthorMinMaxColumns { affiliationIdentifier: String } -type DatasetAuthorGroupByOptions { - dataset: DatasetGroupByOptions - id: Int - authorListOrder: Int - orcid: String - name: String - email: String - affiliationName: String - affiliationAddress: String - affiliationIdentifier: String - correspondingAuthorStatus: Boolean - primaryAuthorStatus: Boolean -} - enum DatasetAuthorCountColumns { dataset id @@ -2902,18 +3059,6 @@ type FrameMinMaxColumns { id: Int } -type FrameGroupByOptions { - deposition: DepositionGroupByOptions - run: RunGroupByOptions - rawAngle: Float - acquisitionOrder: Int - dose: Float - isGainCorrected: Boolean - s3FramePath: String - httpsFramePath: String - id: Int -} - enum FrameCountColumns { deposition run @@ -3069,6 +3214,15 @@ type Tiltseries implements EntityInterface & Node { """Binning factor of the aligned tilt series""" alignedTiltseriesBinning: Int + + """Number of pixels in the 3D data fast axis""" + sizeX: Int + + """Number of pixels in the 3D data medium axis""" + sizeY: Int + + """Number of pixels in the 3D data slow axis""" + sizeZ: Int } type TiltseriesAggregate { @@ -3099,6 +3253,9 @@ type TiltseriesNumericalColumns { tiltSeriesQuality: Int pixelSpacing: Float alignedTiltseriesBinning: Int + sizeX: Int + sizeY: Int + sizeZ: Int id: Int } @@ -3131,6 +3288,9 @@ type TiltseriesMinMaxColumns { tiltSeriesQuality: Int pixelSpacing: Float alignedTiltseriesBinning: Int + sizeX: Int + sizeY: Int + sizeZ: Int id: Int } @@ -3168,6 +3328,9 @@ enum TiltseriesCountColumns { isAligned pixelSpacing alignedTiltseriesBinning + sizeX + sizeY + sizeZ id } @@ -3486,69 +3649,6 @@ type TomogramAuthorMinMaxColumns { affiliationIdentifier: String } -type TomogramAuthorGroupByOptions { - tomogram: TomogramGroupByOptions - id: Int - authorListOrder: Int - orcid: String - name: String - email: String - affiliationName: String - affiliationAddress: String - affiliationIdentifier: String - correspondingAuthorStatus: Boolean - primaryAuthorStatus: Boolean -} - -type TomogramGroupByOptions { - alignment: AlignmentGroupByOptions - deposition: DepositionGroupByOptions - run: RunGroupByOptions - tomogramVoxelSpacing: TomogramVoxelSpacingGroupByOptions - name: String - sizeX: Int - sizeY: Int - sizeZ: Int - voxelSpacing: Float - fiducialAlignmentStatus: fiducial_alignment_status_enum - reconstructionMethod: tomogram_reconstruction_method_enum - processing: tomogram_processing_enum - tomogramVersion: Float - processingSoftware: String - reconstructionSoftware: String - isPortalStandard: Boolean - isAuthorSubmitted: Boolean - isVisualizationDefault: Boolean - s3OmezarrDir: String - httpsOmezarrDir: String - s3MrcFile: String - httpsMrcFile: String - scale0Dimensions: String - scale1Dimensions: String - scale2Dimensions: String - ctfCorrected: Boolean - offsetX: Int - offsetY: Int - offsetZ: Int - keyPhotoUrl: String - keyPhotoThumbnailUrl: String - neuroglancerConfig: String - publications: String - relatedDatabaseEntries: String - id: Int - depositionDate: DateTime - releaseDate: DateTime - lastModifiedDate: DateTime -} - -type TomogramVoxelSpacingGroupByOptions { - run: RunGroupByOptions - voxelSpacing: Float - s3Prefix: String - httpsPrefix: String - id: Int -} - enum TomogramAuthorCountColumns { tomogram id @@ -3659,18 +3759,6 @@ type AnnotationFileMinMaxColumns { id: Int } -type AnnotationFileGroupByOptions { - alignment: AlignmentGroupByOptions - annotationShape: AnnotationShapeGroupByOptions - tomogramVoxelSpacing: TomogramVoxelSpacingGroupByOptions - format: String - s3Path: String - httpsPath: String - isVisualizationDefault: Boolean - source: annotation_file_source_enum - id: Int -} - enum AnnotationFileCountColumns { alignment annotationShape @@ -3844,12 +3932,6 @@ type DepositionTypeMinMaxColumns { id: Int } -type DepositionTypeGroupByOptions { - deposition: DepositionGroupByOptions - type: deposition_types_enum - id: Int -} - enum DepositionTypeCountColumns { deposition type @@ -3947,17 +4029,6 @@ type PerSectionAlignmentParametersMinMaxColumns { id: Int } -type PerSectionAlignmentParametersGroupByOptions { - alignment: AlignmentGroupByOptions - zIndex: Int - xOffset: Float - yOffset: Float - volumeXRotation: Float - inPlaneRotation: [[Float!]!] - tiltAngle: Float - id: Int -} - enum PerSectionAlignmentParametersCountColumns { alignment zIndex @@ -4019,13 +4090,6 @@ type GainFileMinMaxColumns { id: Int } -type GainFileGroupByOptions { - run: RunGroupByOptions - s3FilePath: String - httpsFilePath: String - id: Int -} - enum GainFileCountColumns { run s3FilePath @@ -4102,13 +4166,6 @@ type FrameAcquisitionFileMinMaxColumns { id: Int } -type FrameAcquisitionFileGroupByOptions { - run: RunGroupByOptions - s3MdocPath: String - httpsMdocPath: String - id: Int -} - enum FrameAcquisitionFileCountColumns { run s3MdocPath @@ -5569,6 +5626,15 @@ input TiltseriesCreateInput { """Binning factor of the aligned tilt series""" alignedTiltseriesBinning: Int = null + """Number of pixels in the 3D data fast axis""" + sizeX: Int = null + + """Number of pixels in the 3D data medium axis""" + sizeY: Int = null + + """Number of pixels in the 3D data slow axis""" + sizeZ: Int = null + """Numeric identifier (May change!)""" id: Int! } @@ -5675,6 +5741,15 @@ input TiltseriesUpdateInput { """Binning factor of the aligned tilt series""" alignedTiltseriesBinning: Int = null + """Number of pixels in the 3D data fast axis""" + sizeX: Int = null + + """Number of pixels in the 3D data medium axis""" + sizeY: Int = null + + """Number of pixels in the 3D data slow axis""" + sizeZ: Int = null + """Numeric identifier (May change!)""" id: Int } From 36ba07f8c650070caaa5e337b029b3666c8ae4db Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:05:48 -0800 Subject: [PATCH 09/35] feat: Add V2 query for dataset page (#1409) Also switch GQL codegen schema back to prod, now that prod seems stable. Next: Add diff logging for this query. --- .../app/graphql/getDatasetById.server.ts | 12 +- .../app/graphql/getDatasetByIdV2.server.ts | 314 ++++++++++++++++++ .../app/graphql/getRunByIdV2.server.ts | 2 +- .../data-portal/app/hooks/useDatasetById.ts | 13 +- .../data-portal/app/routes/datasets.$id.tsx | 33 +- frontend/packages/data-portal/codegen.ts | 2 +- 6 files changed, 359 insertions(+), 17 deletions(-) create mode 100644 frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts diff --git a/frontend/packages/data-portal/app/graphql/getDatasetById.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetById.server.ts index c6aeb883f..b4c6d5b4a 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetById.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetById.server.ts @@ -34,7 +34,16 @@ const GET_DATASET_BY_ID = gql(` title description - funding_sources { + funding_sources( + order_by: [ + { + funding_agency_name: asc + }, + { + grant_id: asc + } + ] + ) { funding_agency_name grant_id } @@ -56,6 +65,7 @@ const GET_DATASET_BY_ID = gql(` sample_type tissue_name tissue_id + authors( order_by: { author_list_order: asc, diff --git a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts new file mode 100644 index 000000000..5d3c8ad8e --- /dev/null +++ b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts @@ -0,0 +1,314 @@ +import type { + ApolloClient, + ApolloQueryResult, + NormalizedCacheObject, +} from '@apollo/client' + +import { gql } from 'app/__generated_v2__' +import { + Annotation_File_Shape_Type_Enum, + GetDatasetByIdV2Query, + RunWhereClause, +} from 'app/__generated_v2__/graphql' +import { MAX_PER_PAGE } from 'app/constants/pagination' +import { + DEFAULT_TILT_RANGE_MAX, + DEFAULT_TILT_RANGE_MIN, +} from 'app/constants/tiltSeries' +import { FilterState, getFilterState } from 'app/hooks/useFilter' + +const GET_DATASET_BY_ID_QUERY_V2 = gql(` + query GetDatasetByIdV2( + $id: Int, + $runLimit: Int, + $runOffset: Int, + $runFilter: RunWhereClause, + $depositionId: Int + ) { + datasets(where: { id: { _eq: $id } }) { + s3Prefix + + # Key photo + keyPhotoUrl + + # Dataset dates + lastModifiedDate + releaseDate + depositionDate + + # Dataset metadata + id + title + description + + fundingSources( + orderBy: { + fundingAgencyName: asc, + grantId: asc + } + ) { + edges { + node { + fundingAgencyName + grantId + } + } + } + + relatedDatabaseEntries + + # Sample and experiments data + cellComponentName + cellComponentId + cellName + cellStrainName + cellStrainId + cellTypeId + gridPreparation + organismName + organismTaxid + otherSetup + samplePreparation + sampleType + tissueName + tissueId + + authors(orderBy: { authorListOrder: asc }) { + edges { + node { + correspondingAuthorStatus + email + name + orcid + primaryAuthorStatus + } + } + } + + authorsWithAffiliation: authors(where: { affiliationName: { _is_null: false } }) { + edges { + node { + name + affiliationName + } + } + } + + # Publication info + relatedDatabaseEntries + datasetPublications + + # Tilt Series metadata (via a single run) + runMetadata: runs(first: 1) { + edges { + node { + tiltseries(first: 1) { + edges { + node { + accelerationVoltage + sphericalAberrationConstant + microscopeManufacturer + microscopeModel + microscopeEnergyFilter + microscopePhasePlate + microscopeImageCorrector + microscopeAdditionalInfo + cameraManufacturer + cameraModel + } + } + } + } + } + } + + runsAggregate { + aggregate { + count + } + } + + filteredRunsCount: runsAggregate(where: $runFilter) { + aggregate { + count + } + } + } + + # Runs table + runs( + where: $runFilter, + limitOffset: { + limit: $runLimit, + offset: $runOffset + } + ) { + id + name + tiltseriesAggregate { + aggregate { + avg { + tiltSeriesQuality + } + } + } + annotationsAggregate { + aggregate { + count + groupBy { + objectName + } + } + } + tomograms( + first: 1, + where: { isVisualizationDefault: { _eq: true } } + ) { + edges { + node { + id + keyPhotoThumbnailUrl + neuroglancerConfig + } + } + } + } + + # Filter selectors + annotationsAggregate(where: { run: { datasetId: { _eq: $id }}}) { + aggregate { + count + groupBy { + objectName + } + } + } + annotationShapesAggregate(where: { annotation: { run: { datasetId: { _eq: $id }}}}) { + aggregate { + count + groupBy { + shapeType + } + } + } + tiltseriesAggregate(where: { run: { datasetId: { _eq: $id }}}) { + aggregate { + count + groupBy { + tiltSeriesQuality + } + } + } + + # Deposition banner + depositions(where: { id: { _eq: $depositionId }}) { + id + title + } + } +`) + +function getRunFilter( + filterState: FilterState, + datasetId: number, +): RunWhereClause { + const where: RunWhereClause = { + datasetId: { + _eq: datasetId, + }, + } + + // Deposition filter: + const depositionId = +(filterState.ids.deposition ?? Number.NaN) + if (!Number.isNaN(depositionId) && depositionId > 0) { + where.dataset = { + depositionId: { _eq: depositionId }, + } + } + + // Tilt series filters: + const tiltRangeMin = parseFloat(filterState.tiltSeries.min) + const tiltRangeMax = parseFloat(filterState.tiltSeries.max) + if ( + Number.isFinite(tiltRangeMin) || + Number.isFinite(tiltRangeMax) || + filterState.tiltSeries.qualityScore.length > 0 + ) { + where.tiltseries = {} + } + if (Number.isFinite(tiltRangeMin) || Number.isFinite(tiltRangeMax)) { + where.tiltseries!.tiltRange = { + _gte: Number.isFinite(tiltRangeMin) + ? tiltRangeMin + : DEFAULT_TILT_RANGE_MIN, + _lte: Number.isFinite(tiltRangeMax) + ? tiltRangeMax + : DEFAULT_TILT_RANGE_MAX, + } + } + if (filterState.tiltSeries.qualityScore.length > 0) { + where.tiltseries!.tiltSeriesQuality = { + _in: filterState.tiltSeries.qualityScore + .map(parseInt) + .filter((val) => Number.isFinite(val)), + } + } + + // Annotation filters: + if ( + filterState.includedContents.isGroundTruthEnabled || + filterState.annotation.objectNames.length > 0 || + filterState.annotation.objectShapeTypes.length > 0 || + filterState.annotation.objectId !== null + ) { + where.annotations = {} + } + if (filterState.includedContents.isGroundTruthEnabled) { + where.annotations!.groundTruthStatus = { _eq: true } + } + if (filterState.annotation.objectNames.length > 0) { + where.annotations!.objectName = { + _in: filterState.annotation.objectNames, + } + } + if (filterState.annotation.objectShapeTypes.length > 0) { + where.annotations!.annotationShapes = { + shapeType: { + _in: filterState.annotation + .objectShapeTypes as Annotation_File_Shape_Type_Enum[], // TODO(bchu): Remove typecast. + }, + } + } + if (filterState.annotation.objectId !== null) { + where.annotations!.objectId = { + _ilike: `%${filterState.annotation.objectId.replace(':', '_')}`, // _ is wildcard + } + } + + return where +} + +export async function getDatasetByIdV2({ + client, + depositionId, + id, + page = 1, + params = new URLSearchParams(), +}: { + client: ApolloClient + depositionId?: number + id: number + page?: number + params?: URLSearchParams +}): Promise> { + return client.query({ + query: GET_DATASET_BY_ID_QUERY_V2, + variables: { + id, + depositionId, + runLimit: MAX_PER_PAGE, + runOffset: (page - 1) * MAX_PER_PAGE, + runFilter: getRunFilter(getFilterState(params), id), + }, + }) +} diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts index 030b166dd..1d1683fdf 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts @@ -398,7 +398,7 @@ function getAnnotationShapesFilter( } if (objectId) { where.annotation!.objectId = { - _ilike: `%${objectId.replace(':', '_')}`, + _ilike: `%${objectId.replace(':', '_')}`, // _ is wildcard } } if (methodTypes.length > 0) { diff --git a/frontend/packages/data-portal/app/hooks/useDatasetById.ts b/frontend/packages/data-portal/app/hooks/useDatasetById.ts index 865330693..f5f7236fa 100644 --- a/frontend/packages/data-portal/app/hooks/useDatasetById.ts +++ b/frontend/packages/data-portal/app/hooks/useDatasetById.ts @@ -2,12 +2,17 @@ import { useMemo } from 'react' import { useTypedLoaderData } from 'remix-typedjson' import { GetDatasetByIdQuery } from 'app/__generated__/graphql' +import { GetDatasetByIdV2Query } from 'app/__generated_v2__/graphql' export function useDatasetById() { - const { - datasets: [dataset], - deposition, - } = useTypedLoaderData() + const { v1 } = useTypedLoaderData<{ + v1: GetDatasetByIdQuery + v2: GetDatasetByIdV2Query + }>() + + const dataset = v1.datasets[0] + + const { deposition } = v1 const objectNames = useMemo( () => diff --git a/frontend/packages/data-portal/app/routes/datasets.$id.tsx b/frontend/packages/data-portal/app/routes/datasets.$id.tsx index 51c44f8cb..b8f15f278 100644 --- a/frontend/packages/data-portal/app/routes/datasets.$id.tsx +++ b/frontend/packages/data-portal/app/routes/datasets.$id.tsx @@ -2,7 +2,7 @@ import { json, LoaderFunctionArgs } from '@remix-run/server-runtime' -import { apolloClient } from 'app/apollo.server' +import { apolloClient, apolloClientV2 } from 'app/apollo.server' import { DatasetMetadataDrawer } from 'app/components/Dataset' import { DatasetHeader } from 'app/components/Dataset/DatasetHeader' import { RunsTable } from 'app/components/Dataset/RunsTable' @@ -14,6 +14,7 @@ import { TablePageLayout } from 'app/components/TablePageLayout' import { RUN_FILTERS } from 'app/constants/filterQueryParams' import { QueryParams } from 'app/constants/query' import { getDatasetById } from 'app/graphql/getDatasetById.server' +import { getDatasetByIdV2 } from 'app/graphql/getDatasetByIdV2.server' import { useDatasetById } from 'app/hooks/useDatasetById' import { useI18n } from 'app/hooks/useI18n' import { useQueryParam } from 'app/hooks/useQueryParam' @@ -37,22 +38,34 @@ export async function loader({ params, request }: LoaderFunctionArgs) { }) } - const { data } = await getDatasetById({ - id, - page, - client: apolloClient, - params: url.searchParams, - depositionId: Number.isNaN(depositionId) ? undefined : depositionId, - }) + const [{ data: responseV1 }, { data: responseV2 }] = await Promise.all([ + getDatasetById({ + id, + page, + client: apolloClient, + params: url.searchParams, + depositionId: Number.isNaN(depositionId) ? undefined : depositionId, + }), + getDatasetByIdV2({ + id, + page, + client: apolloClientV2, + params: url.searchParams, + depositionId: Number.isNaN(depositionId) ? undefined : depositionId, + }), + ]) - if (data.datasets.length === 0) { + if (responseV1.datasets.length === 0) { throw new Response(null, { status: 404, statusText: `Dataset with ID ${id} not found`, }) } - return json(data) + return json({ + v1: responseV1, + v2: responseV2, + }) } export default function DatasetByIdPage() { diff --git a/frontend/packages/data-portal/codegen.ts b/frontend/packages/data-portal/codegen.ts index c83c37b0e..7f0781eb9 100644 --- a/frontend/packages/data-portal/codegen.ts +++ b/frontend/packages/data-portal/codegen.ts @@ -6,7 +6,7 @@ const SCHEMA_URL = const SCHEMA_URL_V2 = process.env.API_URL_V2 || - 'https://graphql.cryoet.staging.si.czi.technology/graphql' + 'https://graphql.cryoetdataportal.czscience.com/graphql' const config: CodegenConfig = { generates: { From 78b8fa98696c0f2a3668e2aacb691ef4f4e6f00c Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:24:14 -0800 Subject: [PATCH 10/35] fix: Fix more run page diff logs (#1414) Don't need to query `id` from `methodLinks`. --- .../app/graphql/getRunByIdDiffer.ts | 30 +++++++++++++++---- .../app/graphql/getRunByIdV2.server.ts | 1 - 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts index 304a37e2c..4fab94146 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts @@ -12,7 +12,7 @@ import { Tomogram_Reconstruction_Method_Enum, } from 'app/__generated_v2__/graphql' -/* eslint-disable no-console, no-param-reassign */ +/* eslint-disable no-console, no-param-reassign, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return */ export function logIfHasDiff( url: string, v1: GetRunByIdQuery, @@ -29,8 +29,14 @@ export function logIfHasDiff( delete annotationFile.node.alignmentId } // Sort annotation files for consistency. - annotationShape.annotationFiles.edges.sort((edge) => - edge.node.format.localeCompare(edge.node.format), + annotationShape.annotationFiles.edges.sort( + (annotationFileA, annotationFileB) => + annotationFileA.node.format.localeCompare(annotationFileB.node.format), + ) + // Sort method links for consistency. + annotationShape.annotation?.methodLinks.edges.sort( + (methodLinkA, methodLinkB) => + methodLinkA.node.link.localeCompare(methodLinkB.node.link), ) } for (const tomogram of v2.tomograms) { @@ -190,6 +196,7 @@ export function logIfHasDiff( shapeType: file.shape_type as Annotation_File_Shape_Type_Enum, annotationFiles: { edges: file.annotation.files + .filter((nestedFile) => nestedFile.shape_type === file.shape_type) .map((nestedFile) => ({ node: { format: nestedFile.format, @@ -212,7 +219,18 @@ export function logIfHasDiff( isCuratorRecommended: file.annotation.is_curator_recommended, lastModifiedDate: `${file.annotation.last_modified_date}T00:00:00+00:00`, methodLinks: { - edges: [], + edges: file.annotation.method_links + ?.map((methodLink: any) => ({ + node: { + link: methodLink.link, + linkType: methodLink.link_type, + name: methodLink.custom_name, + }, + })) + .sort( + (methodLinkA: any, methodLinkB: any) => + methodLinkA.node.link?.localeCompare(methodLinkB.node.link), + ), }, methodType: file.annotation.method_type as Annotation_Method_Type_Enum, objectCount: file.annotation.object_count, @@ -295,9 +313,9 @@ export function logIfHasDiff( if (Object.keys(diffObject).length > 0) { console.log( - `DIFF AT ${url} ========== ${JSON.stringify( + `DIFF AT ${url} ======================================== ${JSON.stringify( v1Transformed, - )} ========== ${JSON.stringify(v2)}`, + )} ======================================== ${JSON.stringify(v2)}`, ) } } diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts index 1d1683fdf..3c1408256 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts @@ -238,7 +238,6 @@ const GET_RUN_BY_ID_QUERY_V2 = gql(` methodLinks { edges { node { - id link linkType name From dfa489c7be16afe6e11c94811966087fdb74e0f3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 09:01:00 -0800 Subject: [PATCH 11/35] chore(main): release cryoet-data-portal-python-client 4.3.0 (#1408) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit :robot: I have created a release *beep* *boop* --- ## [4.3.0](https://github.com/chanzuckerberg/cryoet-data-portal/compare/cryoet-data-portal-python-client-v4.2.1...cryoet-data-portal-python-client-v4.3.0) (2024-12-19) ### ✨ Features * add size fields to TiltSeries ([#1406](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1406)) ([3b8e709](https://github.com/chanzuckerberg/cryoet-data-portal/commit/3b8e709a5d44be4085be54c780723fb6910fb521)) ### 🧹 Miscellaneous Chores * update python matrix ([#1407](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1407)) ([639cd90](https://github.com/chanzuckerberg/cryoet-data-portal/commit/639cd901ca4c0def4baa1bdd6e8bd1aeb011a46e)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- client/python/cryoet_data_portal/CHANGELOG.md | 12 ++++++++++++ client/python/cryoet_data_portal/pyproject.toml | 2 +- .../src/cryoet_data_portal/__init__.py | 2 +- release-please.manifest.json | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/client/python/cryoet_data_portal/CHANGELOG.md b/client/python/cryoet_data_portal/CHANGELOG.md index 44b029e67..56df1503d 100644 --- a/client/python/cryoet_data_portal/CHANGELOG.md +++ b/client/python/cryoet_data_portal/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [4.3.0](https://github.com/chanzuckerberg/cryoet-data-portal/compare/cryoet-data-portal-python-client-v4.2.1...cryoet-data-portal-python-client-v4.3.0) (2024-12-19) + + +### ✨ Features + +* add size fields to TiltSeries ([#1406](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1406)) ([3b8e709](https://github.com/chanzuckerberg/cryoet-data-portal/commit/3b8e709a5d44be4085be54c780723fb6910fb521)) + + +### 🧹 Miscellaneous Chores + +* update python matrix ([#1407](https://github.com/chanzuckerberg/cryoet-data-portal/issues/1407)) ([639cd90](https://github.com/chanzuckerberg/cryoet-data-portal/commit/639cd901ca4c0def4baa1bdd6e8bd1aeb011a46e)) + ## [4.2.1](https://github.com/chanzuckerberg/cryoet-data-portal/compare/cryoet-data-portal-python-client-v4.2.0...cryoet-data-portal-python-client-v4.2.1) (2024-12-06) diff --git a/client/python/cryoet_data_portal/pyproject.toml b/client/python/cryoet_data_portal/pyproject.toml index d02ae344f..b212bee8f 100644 --- a/client/python/cryoet_data_portal/pyproject.toml +++ b/client/python/cryoet_data_portal/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "cryoet_data_portal" -version = "4.2.1" +version = "4.3.0" description = "API Client to facilitate the use of the CryoET Portal. For more information about the API and the project visit https://github.com/chanzuckerberg/cryoet-data-portal/" authors = [ { name = "Chan Zuckerberg Initiative", email = "cryoetdataportal@chanzuckerberg.com" }, diff --git a/client/python/cryoet_data_portal/src/cryoet_data_portal/__init__.py b/client/python/cryoet_data_portal/src/cryoet_data_portal/__init__.py index 2f30e555e..87c3da21f 100644 --- a/client/python/cryoet_data_portal/src/cryoet_data_portal/__init__.py +++ b/client/python/cryoet_data_portal/src/cryoet_data_portal/__init__.py @@ -30,7 +30,7 @@ TomogramVoxelSpacing, ) -__version__ = "4.2.1" +__version__ = "4.3.0" __all__ = [ "Client", diff --git a/release-please.manifest.json b/release-please.manifest.json index 9a2008ea2..d58d4d757 100644 --- a/release-please.manifest.json +++ b/release-please.manifest.json @@ -1,4 +1,4 @@ { "frontend": "1.37.2", - "client/python/cryoet_data_portal": "4.2.1" + "client/python/cryoet_data_portal": "4.3.0" } From 4ee07f7f183d7fed8dbdfb51f600cd90cb8825e9 Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:43:04 -0800 Subject: [PATCH 12/35] feat: Add diff logging for dataset page (#1419) * Ordre by * eslint * null --- .../app/graphql/getDatasetById.server.ts | 3 +- .../app/graphql/getDatasetByIdDiffer.ts | 278 +++++++++ .../app/graphql/getDatasetByIdV2.server.ts | 5 +- .../app/graphql/getRunByIdV2.server.ts | 540 +++++++++--------- .../data-portal/app/routes/datasets.$id.tsx | 8 + 5 files changed, 560 insertions(+), 274 deletions(-) create mode 100644 frontend/packages/data-portal/app/graphql/getDatasetByIdDiffer.ts diff --git a/frontend/packages/data-portal/app/graphql/getDatasetById.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetById.server.ts index b4c6d5b4a..6d07d3ec0 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetById.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetById.server.ts @@ -48,8 +48,6 @@ const GET_DATASET_BY_ID = gql(` grant_id } - related_database_entries - # Sample and experiments data cell_component_name cell_component_id @@ -107,6 +105,7 @@ const GET_DATASET_BY_ID = gql(` limit: $run_limit, offset: $run_offset, where: $filter, + order_by: { name: asc } ) { id name diff --git a/frontend/packages/data-portal/app/graphql/getDatasetByIdDiffer.ts b/frontend/packages/data-portal/app/graphql/getDatasetByIdDiffer.ts new file mode 100644 index 000000000..010c3d9d6 --- /dev/null +++ b/frontend/packages/data-portal/app/graphql/getDatasetByIdDiffer.ts @@ -0,0 +1,278 @@ +import { diff } from 'deep-object-diff' + +import { GetDatasetByIdQuery } from 'app/__generated__/graphql' +import { + Annotation_File_Shape_Type_Enum, + GetDatasetByIdV2Query, + Sample_Type_Enum, + Tiltseries_Microscope_Manufacturer_Enum, +} from 'app/__generated_v2__/graphql' + +/* eslint-disable no-console, no-param-reassign */ +export function logIfHasDiff( + url: string, + v1: GetDatasetByIdQuery, + v2: GetDatasetByIdV2Query, +): void { + console.log('Checking for dataset query diffs') + + v2 = structuredClone(v2) + + // Counts not used. + for (const run of v2.runs) { + for (const annotationsAggregate of run.annotationsAggregate?.aggregate ?? + []) { + delete annotationsAggregate.count + } + // Consistent sort order. + run.annotationsAggregate?.aggregate?.sort((groupA, groupB) => + groupA.groupBy!.objectName!.localeCompare(groupB.groupBy!.objectName!), + ) + } + for (const annotationsAggreate of v2.annotationsAggregate.aggregate ?? []) { + delete annotationsAggreate.count + } + for (const annotationShapesAggregate of v2.annotationShapesAggregate + .aggregate ?? []) { + delete annotationShapesAggregate.count + } + for (const tiltseriesAggregate of v2.tiltseriesAggregate.aggregate ?? []) { + delete tiltseriesAggregate.count + } + // Consistent sort order. + v2.annotationsAggregate.aggregate?.sort((groupA, groupB) => + groupA.groupBy!.objectName!.localeCompare(groupB.groupBy!.objectName!), + ) + v2.annotationShapesAggregate.aggregate?.sort((groupA, groupB) => + groupA.groupBy!.shapeType!.localeCompare(groupB.groupBy!.shapeType!), + ) + v2.tiltseriesAggregate.aggregate?.sort( + (groupA, groupB) => + groupA.groupBy!.tiltSeriesQuality! - groupB.groupBy!.tiltSeriesQuality!, + ) + + const v1Transformed: GetDatasetByIdV2Query = { + datasets: v1.datasets.map((dataset) => ({ + s3Prefix: dataset.s3_prefix, + keyPhotoUrl: dataset.key_photo_url, + lastModifiedDate: `${dataset.last_modified_date}T00:00:00+00:00`, + releaseDate: `${dataset.release_date}T00:00:00+00:00`, + depositionDate: `${dataset.deposition_date}T00:00:00+00:00`, + id: dataset.id, + title: dataset.title, + description: dataset.description, + fundingSources: { + edges: dataset.funding_sources.map((source) => ({ + node: { + fundingAgencyName: source.funding_agency_name, + grantId: source.grant_id, + }, + })), + }, + cellComponentName: dataset.cell_component_name, + cellComponentId: dataset.cell_component_id, + cellName: dataset.cell_name, + cellStrainName: dataset.cell_strain_name, + cellStrainId: dataset.cell_strain_id, + cellTypeId: dataset.cell_type_id, + gridPreparation: dataset.grid_preparation, + organismName: dataset.organism_name, + organismTaxid: + dataset.organism_taxid != null + ? Number(dataset.organism_taxid) + : dataset.organism_taxid, + otherSetup: dataset.other_setup, + samplePreparation: dataset.sample_preparation, + sampleType: dataset.sample_type as Sample_Type_Enum, + tissueName: dataset.tissue_name, + tissueId: dataset.tissue_id, + authors: { + edges: dataset.authors.map((author) => ({ + node: { + correspondingAuthorStatus: author.corresponding_author_status, + email: author.email, + name: author.name, + orcid: author.orcid, + primaryAuthorStatus: author.primary_author_status, + }, + })), + }, + authorsWithAffiliation: { + edges: dataset.authors_with_affiliation.map((author) => ({ + node: { + name: author.name, + affiliationName: author.affiliation_name, + }, + })), + }, + relatedDatabaseEntries: dataset.related_database_entries, + datasetPublications: dataset.dataset_publications, + runMetadata: { + edges: dataset.run_metadata.map((run) => ({ + node: { + tiltseries: { + edges: run.tiltseries.map((tiltseries) => ({ + node: { + accelerationVoltage: tiltseries.acceleration_voltage, + sphericalAberrationConstant: + tiltseries.spherical_aberration_constant, + microscopeManufacturer: + tiltseries.microscope_manufacturer as Tiltseries_Microscope_Manufacturer_Enum, + microscopeModel: tiltseries.microscope_model, + microscopeEnergyFilter: tiltseries.microscope_energy_filter, + microscopePhasePlate: tiltseries.microscope_phase_plate, + microscopeImageCorrector: + tiltseries.microscope_image_corrector, + microscopeAdditionalInfo: + tiltseries.microscope_additional_info, + cameraManufacturer: tiltseries.camera_manufacturer, + cameraModel: tiltseries.camera_model, + }, + })), + }, + }, + })), + }, + runsAggregate: { + aggregate: [ + { + count: dataset.runs_aggregate.aggregate?.count, + }, + ], + }, + filteredRunsCount: { + aggregate: [ + { + count: dataset.filtered_runs_count.aggregate?.count, + }, + ], + }, + })), + runs: v1.datasets[0].runs.map((run) => ({ + id: run.id, + name: run.name, + tiltseriesAggregate: { + aggregate: [ + { + avg: { + tiltSeriesQuality: + run.tiltseries_aggregate.aggregate?.avg?.tilt_series_quality, + }, + }, + ], + }, + annotationsAggregate: { + aggregate: [ + ...new Set( + run.tomogram_voxel_spacings.flatMap((tomogramVoxelSpacing) => + tomogramVoxelSpacing.annotations.map( + (annotation) => annotation.object_name, + ), + ), + ), + ] + .map((uniqueObjectName) => ({ + groupBy: { + objectName: uniqueObjectName, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.objectName.localeCompare(groupB.groupBy.objectName), + ), + }, + tomograms: { + edges: run.tomogram_voxel_spacings + .flatMap((tvs) => tvs.tomograms) + .filter((tomogram) => tomogram.neuroglancer_config) + .map((tomogram) => ({ + node: { + id: tomogram.id, + keyPhotoThumbnailUrl: tomogram.key_photo_thumbnail_url, + neuroglancerConfig: tomogram.neuroglancer_config, + }, + })), + }, + })), + annotationsAggregate: { + aggregate: [ + ...new Set( + v1.datasets[0].run_stats.flatMap((run) => + run.tomogram_voxel_spacings.flatMap((tomogramVoxelSpacing) => + tomogramVoxelSpacing.annotations.map( + (annotation) => annotation.object_name, + ), + ), + ), + ), + ] + .map((uniqueObjectName) => ({ + groupBy: { + objectName: uniqueObjectName, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.objectName.localeCompare(groupB.groupBy.objectName), + ), + }, + annotationShapesAggregate: { + aggregate: [ + ...new Set( + v1.datasets[0].run_stats.flatMap((run) => + run.tomogram_voxel_spacings.flatMap((tomogramVoxelSpacing) => + tomogramVoxelSpacing.annotations.flatMap((annotation) => + annotation.files.map((file) => file.shape_type), + ), + ), + ), + ), + ] + .map((uniqueShapeType) => ({ + groupBy: { + shapeType: uniqueShapeType as Annotation_File_Shape_Type_Enum, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.shapeType.localeCompare(groupB.groupBy.shapeType), + ), + }, + tiltseriesAggregate: { + aggregate: [ + ...new Set( + v1.datasets[0].run_stats.flatMap((run) => + run.tiltseries.map((tiltseries) => tiltseries.tilt_series_quality), + ), + ), + ] + .map((uniqueObjectName) => ({ + groupBy: { + tiltSeriesQuality: uniqueObjectName, + }, + })) + .sort( + (groupA, groupB) => + groupA.groupBy.tiltSeriesQuality - groupB.groupBy.tiltSeriesQuality, + ), + }, + depositions: + v1.deposition != null + ? [ + { + id: v1.deposition.id, + title: v1.deposition.title, + }, + ] + : [], + } + + const diffObject = diff(v1Transformed, v2) + + if (Object.keys(diffObject).length > 0) { + console.log( + `DIFF AT ${url} ================================================================================ ${JSON.stringify( + v1Transformed, + )} ================================================================================ ${JSON.stringify( + v2, + )}`, + ) + } +} diff --git a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts index 5d3c8ad8e..3ab12bc82 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts @@ -55,8 +55,6 @@ const GET_DATASET_BY_ID_QUERY_V2 = gql(` } } - relatedDatabaseEntries - # Sample and experiments data cellComponentName cellComponentId @@ -138,6 +136,9 @@ const GET_DATASET_BY_ID_QUERY_V2 = gql(` # Runs table runs( where: $runFilter, + orderBy: { + name: asc + }, limitOffset: { limit: $runLimit, offset: $runOffset diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts index 3c1408256..ff4a14225 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts @@ -15,314 +15,243 @@ import { MAX_PER_PAGE } from 'app/constants/pagination' import { FilterState, getFilterState } from 'app/hooks/useFilter' const GET_RUN_BY_ID_QUERY_V2 = gql(` - query GetRunByIdV2( - $id: Int - $limit: Int - $annotationShapesOffset: Int - $annotationShapesFilter: AnnotationShapeWhereClause - ) { - runs(where: { id: { _eq: $id } }) { - id - name + query GetRunByIdV2( + $id: Int + $limit: Int + $annotationShapesOffset: Int + $annotationShapesFilter: AnnotationShapeWhereClause + ) { + runs(where: { id: { _eq: $id } }) { + id + name - # Metadata sidebar - tiltseries(first: 1) { - edges { - node { - accelerationVoltage - alignedTiltseriesBinning - binningFromFrames - cameraManufacturer - cameraModel - dataAcquisitionSoftware - id - isAligned - microscopeAdditionalInfo - microscopeEnergyFilter - microscopeImageCorrector - microscopeManufacturer - microscopeModel - microscopePhasePlate - pixelSpacing - relatedEmpiarEntry - sphericalAberrationConstant - tiltAxis - tiltMax - tiltMin - tiltRange - tiltSeriesQuality - tiltStep - tiltingScheme - totalFlux - } + # Metadata sidebar + tiltseries(first: 1) { + edges { + node { + accelerationVoltage + alignedTiltseriesBinning + binningFromFrames + cameraManufacturer + cameraModel + dataAcquisitionSoftware + id + isAligned + microscopeAdditionalInfo + microscopeEnergyFilter + microscopeImageCorrector + microscopeManufacturer + microscopeModel + microscopePhasePlate + pixelSpacing + relatedEmpiarEntry + sphericalAberrationConstant + tiltAxis + tiltMax + tiltMin + tiltRange + tiltSeriesQuality + tiltStep + tiltingScheme + totalFlux } } + } - dataset { - cellComponentName - cellComponentId - cellName - cellStrainName - cellStrainId - cellTypeId - depositionDate - description - gridPreparation - id - lastModifiedDate - organismName - organismTaxid - otherSetup - datasetPublications - relatedDatabaseEntries - relatedDatabaseEntries - releaseDate - s3Prefix - samplePreparation - sampleType - tissueName - tissueId - title + dataset { + cellComponentName + cellComponentId + cellName + cellStrainName + cellStrainId + cellTypeId + depositionDate + description + gridPreparation + id + lastModifiedDate + organismName + organismTaxid + otherSetup + datasetPublications + relatedDatabaseEntries + relatedDatabaseEntries + releaseDate + s3Prefix + samplePreparation + sampleType + tissueName + tissueId + title - fundingSources( - orderBy: { - fundingAgencyName: asc - grantId: asc - } - ) { - edges { - node { - fundingAgencyName - grantId - } - } + fundingSources( + orderBy: { + fundingAgencyName: asc + grantId: asc } - - authors( - orderBy: { - authorListOrder: asc, - }, - ) { - edges { - node { - correspondingAuthorStatus - email - name - orcid - primaryAuthorStatus - } + ) { + edges { + node { + fundingAgencyName + grantId } } } - # Legacy single tomogram - tomogramVoxelSpacings( - first: 1 - # where: { - # tomograms: { - # isAuthorSubmitted: { _eq: true} # TODO(bchu): Uncomment when bool bug fixed AND isAuthorSubmitted is populated. - # } - # } + authors( + orderBy: { + authorListOrder: asc, + }, ) { edges { node { - id - s3Prefix - - tomograms( - first: 1 - where: { - isVisualizationDefault: { _eq: true } - } - # where: { - # isAuthorSubmitted: { _eq: true } # TODO(bchu): Uncomment when bool bug fixed. - # } - ) { - edges { - node { - ctfCorrected - fiducialAlignmentStatus - id - keyPhotoUrl - name - neuroglancerConfig - processing - processingSoftware - reconstructionMethod - reconstructionSoftware - sizeX - sizeY - sizeZ - voxelSpacing - alignment { - affineTransformationMatrix - } - } - } - } + correspondingAuthorStatus + email + name + orcid + primaryAuthorStatus } } } + } - # Header - framesAggregate { - aggregate { - count - } - } - tiltseriesAggregate { - aggregate { - count - avg { - tiltSeriesQuality + # Legacy single tomogram + tomogramVoxelSpacings( + first: 1 + # where: { + # tomograms: { + # isAuthorSubmitted: { _eq: true} # TODO(bchu): Uncomment when bool bug fixed AND isAuthorSubmitted is populated. + # } + # } + ) { + edges { + node { + id + s3Prefix + + tomograms( + first: 1 + where: { + isVisualizationDefault: { _eq: true } + } + # where: { + # isAuthorSubmitted: { _eq: true } # TODO(bchu): Uncomment when bool bug fixed. + # } + ) { + edges { + node { + ctfCorrected + fiducialAlignmentStatus + id + keyPhotoUrl + name + neuroglancerConfig + processing + processingSoftware + reconstructionMethod + reconstructionSoftware + sizeX + sizeY + sizeZ + voxelSpacing + alignment { + affineTransformationMatrix + } + } + } } } } } # Header - alignmentsAggregate(where: {run: {id: {_eq: $id}}}) { + framesAggregate { aggregate { count } } - - # Annotations table - annotationShapes( - where: $annotationShapesFilter - orderBy: [ - { - annotation: { - groundTruthStatus: desc - } - }, - { - annotation: { - depositionDate: desc - } - }, - { - annotation: { - id: desc - } - } - ] - limitOffset: { - limit: $limit - offset: $annotationShapesOffset - } - ) { - shapeType - annotationFiles { - edges { - node { - alignmentId - format - httpsPath - s3Path - } + tiltseriesAggregate { + aggregate { + count + avg { + tiltSeriesQuality } } - annotation { - annotationMethod - annotationPublication - annotationSoftware - confidencePrecision - confidenceRecall - depositionDate - groundTruthStatus - groundTruthUsed - id - isCuratorRecommended - lastModifiedDate - methodLinks { - edges { - node { - link - linkType - name - } - } - } - methodType - objectCount - objectDescription - objectId - objectName - objectState - releaseDate - authors(orderBy: { authorListOrder: asc }) { - edges { - node { - primaryAuthorStatus - correspondingAuthorStatus - name - email - orcid - } - } + } + } + + # Header + alignmentsAggregate(where: {run: {id: {_eq: $id}}}) { + aggregate { + count + } + } + + # Annotations table + annotationShapes( + where: $annotationShapesFilter + orderBy: [ + { + annotation: { + groundTruthStatus: desc } - authorsAggregate { - aggregate { - count - } + }, + { + annotation: { + depositionDate: desc } - deposition { - id - title + }, + { + annotation: { + id: desc } } + ] + limitOffset: { + limit: $limit + offset: $annotationShapesOffset } - - # Tomograms table + download selector - tomograms(where: { run: { id: { _eq: $id } } }) { - alignment { - id - affineTransformationMatrix - alignmentType - tiltOffset - volumeXDimension - volumeYDimension - volumeZDimension - volumeXOffset - volumeYOffset - volumeZOffset - xRotationOffset + ) { + shapeType + annotationFiles { + edges { + node { + alignmentId + format + httpsPath + s3Path + } } - ctfCorrected - fiducialAlignmentStatus - httpsMrcFile + } + annotation { + annotationMethod + annotationPublication + annotationSoftware + confidencePrecision + confidenceRecall + depositionDate + groundTruthStatus + groundTruthUsed id - isPortalStandard - isAuthorSubmitted - isVisualizationDefault - keyPhotoThumbnailUrl - keyPhotoUrl - name - neuroglancerConfig - processing - processingSoftware - reconstructionMethod - reconstructionSoftware - s3MrcFile - s3OmezarrDir - sizeX - sizeY - sizeZ - voxelSpacing - releaseDate + isCuratorRecommended lastModifiedDate - relatedDatabaseEntries - deposition { - id - depositionDate - title - } - tomogramVoxelSpacing { - id - s3Prefix + methodLinks { + edges { + node { + link + linkType + name + } + } } - authors { + methodType + objectCount + objectDescription + objectId + objectName + objectState + releaseDate + authors(orderBy: { authorListOrder: asc }) { edges { node { primaryAuthorStatus @@ -333,8 +262,79 @@ const GET_RUN_BY_ID_QUERY_V2 = gql(` } } } + authorsAggregate { + aggregate { + count + } + } + deposition { + id + title + } + } + } + + # Tomograms table + download selector + tomograms(where: { run: { id: { _eq: $id } } }) { + alignment { + id + affineTransformationMatrix + alignmentType + tiltOffset + volumeXDimension + volumeYDimension + volumeZDimension + volumeXOffset + volumeYOffset + volumeZOffset + xRotationOffset + } + ctfCorrected + fiducialAlignmentStatus + httpsMrcFile + id + isPortalStandard + isAuthorSubmitted + isVisualizationDefault + keyPhotoThumbnailUrl + keyPhotoUrl + name + neuroglancerConfig + processing + processingSoftware + reconstructionMethod + reconstructionSoftware + s3MrcFile + s3OmezarrDir + sizeX + sizeY + sizeZ + voxelSpacing + releaseDate + lastModifiedDate + relatedDatabaseEntries + deposition { + id + depositionDate + title + } + tomogramVoxelSpacing { + id + s3Prefix + } + authors { + edges { + node { + primaryAuthorStatus + correspondingAuthorStatus + name + email + orcid + } + } } } + } `) function getAnnotationShapesFilter( diff --git a/frontend/packages/data-portal/app/routes/datasets.$id.tsx b/frontend/packages/data-portal/app/routes/datasets.$id.tsx index b8f15f278..19ce9c1d4 100644 --- a/frontend/packages/data-portal/app/routes/datasets.$id.tsx +++ b/frontend/packages/data-portal/app/routes/datasets.$id.tsx @@ -14,6 +14,7 @@ import { TablePageLayout } from 'app/components/TablePageLayout' import { RUN_FILTERS } from 'app/constants/filterQueryParams' import { QueryParams } from 'app/constants/query' import { getDatasetById } from 'app/graphql/getDatasetById.server' +import { logIfHasDiff } from 'app/graphql/getDatasetByIdDiffer' import { getDatasetByIdV2 } from 'app/graphql/getDatasetByIdV2.server' import { useDatasetById } from 'app/hooks/useDatasetById' import { useI18n } from 'app/hooks/useI18n' @@ -62,6 +63,13 @@ export async function loader({ params, request }: LoaderFunctionArgs) { }) } + try { + logIfHasDiff(request.url, responseV1, responseV2) + } catch (error) { + // eslint-disable-next-line no-console, @typescript-eslint/restrict-template-expressions + console.log(`DIFF ERROR: ${error}`) + } + return json({ v1: responseV1, v2: responseV2, From 9b823e1fdb678df075e26209b28ad85287635cd7 Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:43:34 -0800 Subject: [PATCH 13/35] fix: Fix affine transformation matrix diff log (#1422) --- .../packages/data-portal/app/graphql/getRunByIdDiffer.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts index 4fab94146..8a2114017 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts @@ -168,10 +168,7 @@ export function logIfHasDiff( alignment: { affineTransformationMatrix: JSON.stringify( tomogram.affine_transformation_matrix, - ) - .replaceAll('[', '{') - .replaceAll(']', '}') - .replaceAll(', ', ','), + ).replaceAll(',', ', '), }, }, })), From 2632ac0b7f8ddedfce50dc8dfa4b2e0fc3b4fb9b Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Mon, 23 Dec 2024 13:32:48 -0800 Subject: [PATCH 14/35] feat: Add deposition to V2 run query (#1424) * rebase * Fix mierge * remove defualt * fix test --- .../app/graphql/getDatasetByIdV2.server.ts | 1 + .../app/graphql/getRunByIdDiffer.ts | 9 ++++++ .../app/graphql/getRunByIdV2.server.ts | 30 +++++++++++++++---- .../data-portal/app/routes/runs.$id.tsx | 12 ++++++-- .../e2e/pageObjects/metadataDrawer/utils.ts | 7 ++++- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts index 3ab12bc82..733b3c6a7 100644 --- a/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getDatasetByIdV2.server.ts @@ -202,6 +202,7 @@ const GET_DATASET_BY_ID_QUERY_V2 = gql(` } # Deposition banner + # Returns empty array if $depositionId not defined depositions(where: { id: { _eq: $depositionId }}) { id title diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts index 8a2114017..e414a2ba3 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts @@ -304,6 +304,15 @@ export function logIfHasDiff( })), }, })), + depositions: + v1.deposition != null + ? [ + { + id: v1.deposition.id, + title: v1.deposition.title, + }, + ] + : [], } const diffObject = diff(v1Transformed, v2) diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts index ff4a14225..503d72226 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts @@ -20,6 +20,7 @@ const GET_RUN_BY_ID_QUERY_V2 = gql(` $limit: Int $annotationShapesOffset: Int $annotationShapesFilter: AnnotationShapeWhereClause + $depositionId: Int ) { runs(where: { id: { _eq: $id } }) { id @@ -334,6 +335,13 @@ const GET_RUN_BY_ID_QUERY_V2 = gql(` } } } + + # Deposition banner + # Returns empty array if $depositionId not defined + depositions(where: { id: { _eq: $depositionId }}) { + id + title + } } `) @@ -414,12 +422,21 @@ function getAnnotationShapesFilter( return where } -export async function getRunByIdV2( - client: ApolloClient, - id: number, - annotationsPage: number, - params: URLSearchParams = new URLSearchParams(), -): Promise> { +export interface GetRunByIdV2Params { + client: ApolloClient + id: number + annotationsPage: number + params: URLSearchParams + depositionId?: number +} + +export async function getRunByIdV2({ + client, + id, + annotationsPage, + params, + depositionId, +}: GetRunByIdV2Params): Promise> { return client.query({ query: GET_RUN_BY_ID_QUERY_V2, variables: { @@ -430,6 +447,7 @@ export async function getRunByIdV2( id, getFilterState(params), ), + depositionId, }, }) } diff --git a/frontend/packages/data-portal/app/routes/runs.$id.tsx b/frontend/packages/data-portal/app/routes/runs.$id.tsx index 25638e7d5..895b921b4 100644 --- a/frontend/packages/data-portal/app/routes/runs.$id.tsx +++ b/frontend/packages/data-portal/app/routes/runs.$id.tsx @@ -47,17 +47,23 @@ export async function loader({ request, params }: LoaderFunctionArgs) { const annotationsPage = +( url.searchParams.get(QueryParams.AnnotationsPage) ?? '1' ) - const depositionId = +(url.searchParams.get(QueryParams.DepositionId) ?? '-1') + const depositionId = Number(url.searchParams.get(QueryParams.DepositionId)) const [{ data: responseV1 }, { data: responseV2 }] = await Promise.all([ getRunById({ id, annotationsPage, - depositionId, + depositionId: Number.isNaN(depositionId) ? undefined : depositionId, client: apolloClient, params: url.searchParams, }), - getRunByIdV2(apolloClientV2, id, annotationsPage, url.searchParams), + getRunByIdV2({ + client: apolloClientV2, + id, + annotationsPage, + params: url.searchParams, + depositionId: Number.isNaN(depositionId) ? undefined : depositionId, + }), ]) if (responseV1.runs.length === 0) { diff --git a/frontend/packages/data-portal/e2e/pageObjects/metadataDrawer/utils.ts b/frontend/packages/data-portal/e2e/pageObjects/metadataDrawer/utils.ts index aa1b7aa73..5953e8282 100644 --- a/frontend/packages/data-portal/e2e/pageObjects/metadataDrawer/utils.ts +++ b/frontend/packages/data-portal/e2e/pageObjects/metadataDrawer/utils.ts @@ -299,7 +299,12 @@ export async function getAnnotationTestData( export async function getTomogramTestData( client: ApolloClient, ) { - const { data } = await getRunByIdV2(client, +E2E_CONFIG.runId, 1) + const { data } = await getRunByIdV2({ + client, + id: +E2E_CONFIG.runId, + annotationsPage: 1, + params: new URLSearchParams(), + }) const tomogram = data.tomograms[0] const { dataset } = data.runs[0] From c46b9e537121e4b14a4ee6dbab21c123a04a215b Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Tue, 24 Dec 2024 09:51:19 -0800 Subject: [PATCH 15/35] feat: Finish converting run page query to V2 (#1425) --- .../app/graphql/getRunByIdDiffer.ts | 122 ++++++++++++++++++ .../app/graphql/getRunByIdV2.server.ts | 93 +++++++++++++ .../data-portal/app/hooks/useRunById.ts | 4 +- 3 files changed, 218 insertions(+), 1 deletion(-) diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts index e414a2ba3..930d99bd5 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdDiffer.ts @@ -54,6 +54,41 @@ export function logIfHasDiff( // There are no frames in V1. delete run.framesAggregate } + // Don't care about counts. + for (const aggregate of v2.uniqueAnnotationSoftwares.aggregate ?? []) { + delete aggregate.count + } + for (const aggregate of v2.uniqueObjectNames.aggregate ?? []) { + delete aggregate.count + } + for (const aggregate of v2.uniqueShapeTypes.aggregate ?? []) { + delete aggregate.count + } + for (const aggregate of v2.uniqueResolutions.aggregate ?? []) { + delete aggregate.count + } + for (const aggregate of v2.uniqueProcessingMethods.aggregate ?? []) { + delete aggregate.count + } + // Consistent sort order. + v2.uniqueAnnotationSoftwares.aggregate?.sort((gropuByA, groupByB) => + gropuByA.groupBy!.annotationSoftware!.localeCompare( + groupByB.groupBy!.annotationSoftware!, + ), + ) + v2.uniqueObjectNames.aggregate?.sort((groupA, groupB) => + groupA.groupBy!.objectName!.localeCompare(groupB.groupBy!.objectName!), + ) + v2.uniqueShapeTypes.aggregate?.sort((groupA, groupB) => + groupA.groupBy!.shapeType!.localeCompare(groupB.groupBy!.shapeType!), + ) + v2.uniqueResolutions.aggregate?.sort( + (groupA, groupB) => + groupA.groupBy!.voxelSpacing! - groupB.groupBy!.voxelSpacing!, + ) + v2.uniqueProcessingMethods.aggregate?.sort((groupA, groupB) => + groupA.groupBy!.processing!.localeCompare(groupB.groupBy!.processing!), + ) const v1Transformed: GetRunByIdV2Query = { runs: v1.runs.map((run) => ({ @@ -304,6 +339,93 @@ export function logIfHasDiff( })), }, })), + uniqueAnnotationSoftwares: { + aggregate: v1.annotations_for_softwares + .map((annotation) => ({ + groupBy: { + annotationSoftware: annotation.annotation_software, + }, + })) + .sort((groupByA, groupByB) => + groupByA.groupBy.annotationSoftware!.localeCompare( + groupByB.groupBy.annotationSoftware!, + ), + ), + }, + uniqueObjectNames: { + aggregate: v1.annotations_for_object_names + .map((annotation) => ({ + groupBy: { + objectName: annotation.object_name, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.objectName.localeCompare(groupB.groupBy.objectName), + ), + }, + uniqueShapeTypes: { + aggregate: v1.annotation_files_for_shape_types + .map((file) => ({ + groupBy: { + shapeType: file.shape_type as Annotation_File_Shape_Type_Enum, + }, + })) + .sort((groupA, groupB) => + groupA.groupBy.shapeType.localeCompare(groupB.groupBy.shapeType), + ), + }, + uniqueResolutions: { + aggregate: v1.tomograms_for_resolutions.map((tomogram) => ({ + groupBy: { + voxelSpacing: tomogram.voxel_spacing, + }, + })), + }, + uniqueProcessingMethods: { + aggregate: v1.tomograms_for_distinct_processing_methods.map( + (tomogram) => ({ + groupBy: { + processing: tomogram.processing as Tomogram_Processing_Enum, + }, + }), + ), + }, + numTotalAnnotationRows: { + aggregate: [ + { + count: v1.annotation_files_aggregate_for_total.aggregate?.count, + }, + ], + }, + numFilteredAnnotationRows: { + aggregate: [ + { + count: v1.annotation_files_aggregate_for_filtered.aggregate?.count, + }, + ], + }, + numFilteredGroundTruthAnnotationRows: { + aggregate: [ + { + count: + v1.annotation_files_aggregate_for_ground_truth.aggregate?.count, + }, + ], + }, + numFilteredOtherAnnotationRows: { + aggregate: [ + { + count: v1.annotation_files_aggregate_for_other.aggregate?.count, + }, + ], + }, + tomogramsAggregate: { + aggregate: [ + { + count: v1.tomograms_aggregate.aggregate?.count, + }, + ], + }, depositions: v1.deposition != null ? [ diff --git a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts index 503d72226..8fc352226 100644 --- a/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts +++ b/frontend/packages/data-portal/app/graphql/getRunByIdV2.server.ts @@ -20,6 +20,8 @@ const GET_RUN_BY_ID_QUERY_V2 = gql(` $limit: Int $annotationShapesOffset: Int $annotationShapesFilter: AnnotationShapeWhereClause + $annotationShapesFilterGroundTruthTrue: AnnotationShapeWhereClause + $annotationShapesFilterGroundTruthFalse: AnnotationShapeWhereClause $depositionId: Int ) { runs(where: { id: { _eq: $id } }) { @@ -336,6 +338,79 @@ const GET_RUN_BY_ID_QUERY_V2 = gql(` } } + # Annotation metadata: + uniqueAnnotationSoftwares: annotationsAggregate(where: { runId: { _eq: $id }}) { + aggregate { + count + groupBy { + annotationSoftware + } + } + } + uniqueObjectNames: annotationsAggregate(where: { runId: { _eq: $id }}) { + aggregate { + count + groupBy { + objectName + } + } + } + uniqueShapeTypes: annotationShapesAggregate(where: { annotation: { runId: { _eq: $id }}}) { + aggregate { + count + groupBy { + shapeType + } + } + } + + # Tomogram metadata: + uniqueResolutions: tomogramVoxelSpacingsAggregate(where: { runId: { _eq: $id }}) { + aggregate { + count + groupBy { + voxelSpacing + } + } + } + uniqueProcessingMethods: tomogramsAggregate(where: { runId: { _eq: $id }}) { + aggregate { + count + groupBy { + processing + } + } + } + + # Annotation counts: + numTotalAnnotationRows: annotationShapesAggregate(where: { annotation: { runId: { _eq: $id }}}) { + aggregate { + count + } + } + numFilteredAnnotationRows: annotationShapesAggregate(where: $annotationShapesFilter) { + aggregate { + count + } + } + numFilteredGroundTruthAnnotationRows: annotationShapesAggregate(where: $annotationShapesFilterGroundTruthTrue) { + aggregate { + count + } + } + numFilteredOtherAnnotationRows: annotationShapesAggregate(where: $annotationShapesFilterGroundTruthFalse) { + aggregate { + count + } + } + + # Tomogram counts: + tomogramsAggregate(where: { runId: { _eq: $id }}) { + aggregate { + count + } + } + # Deposition banner # Returns empty array if $depositionId not defined depositions(where: { id: { _eq: $depositionId }}) { @@ -348,6 +423,7 @@ const GET_RUN_BY_ID_QUERY_V2 = gql(` function getAnnotationShapesFilter( runId: number, filterState: FilterState, + groundTruthStatus?: boolean, ): AnnotationShapeWhereClause { const where: AnnotationShapeWhereClause = { annotation: { @@ -419,6 +495,13 @@ function getAnnotationShapesFilter( } } + // Ground truth dividers + if (groundTruthStatus !== undefined) { + where.annotation!.groundTruthStatus = { + _eq: groundTruthStatus, + } + } + return where } @@ -447,6 +530,16 @@ export async function getRunByIdV2({ id, getFilterState(params), ), + annotationShapesFilterGroundTruthTrue: getAnnotationShapesFilter( + id, + getFilterState(params), + /* groundTruthStatus */ true, + ), + annotationShapesFilterGroundTruthFalse: getAnnotationShapesFilter( + id, + getFilterState(params), + /* groundTruthStatus */ false, + ), depositionId, }, }) diff --git a/frontend/packages/data-portal/app/hooks/useRunById.ts b/frontend/packages/data-portal/app/hooks/useRunById.ts index 34ed37bcf..80c2d4c5e 100644 --- a/frontend/packages/data-portal/app/hooks/useRunById.ts +++ b/frontend/packages/data-portal/app/hooks/useRunById.ts @@ -40,6 +40,7 @@ export function useRunById() { return t2.id - t1.id }) + // TODO(bchu): Sort manually in V2. const processingMethods = v1.tomograms_for_distinct_processing_methods.map( (tomogram) => tomogram.processing, ) @@ -56,6 +57,7 @@ export function useRunById() { .map((annotation) => annotation.annotation_software) .filter(isDefined) + // TODO(bchu): Sort manually in V2. const resolutions = v1.tomograms_for_resolutions.map( (tomogram) => tomogram.voxel_spacing, ) @@ -73,7 +75,7 @@ export function useRunById() { const alignmentsCount = v2.alignmentsAggregate.aggregate?.[0]?.count ?? 0 - const { deposition } = v1 + const deposition = v2.depositions[0] return { run, From bec698e6a391012f82c9c482196bbe06ac5c25c6 Mon Sep 17 00:00:00 2001 From: Bryan Chu <151689101+bchu1@users.noreply.github.com> Date: Tue, 24 Dec 2024 09:52:34 -0800 Subject: [PATCH 16/35] feat: Use some V2 fields in dataset page (#1427) --- .../data-portal/app/hooks/useDatasetById.ts | 37 +++---------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/frontend/packages/data-portal/app/hooks/useDatasetById.ts b/frontend/packages/data-portal/app/hooks/useDatasetById.ts index f5f7236fa..cdceaad4d 100644 --- a/frontend/packages/data-portal/app/hooks/useDatasetById.ts +++ b/frontend/packages/data-portal/app/hooks/useDatasetById.ts @@ -1,49 +1,24 @@ -import { useMemo } from 'react' import { useTypedLoaderData } from 'remix-typedjson' import { GetDatasetByIdQuery } from 'app/__generated__/graphql' import { GetDatasetByIdV2Query } from 'app/__generated_v2__/graphql' export function useDatasetById() { - const { v1 } = useTypedLoaderData<{ + const { v1, v2 } = useTypedLoaderData<{ v1: GetDatasetByIdQuery v2: GetDatasetByIdV2Query }>() const dataset = v1.datasets[0] - const { deposition } = v1 + const deposition = v2.depositions[0] - const objectNames = useMemo( - () => - Array.from( - new Set( - dataset.run_stats.flatMap((run) => - run.tomogram_voxel_spacings.flatMap((voxelSpacing) => - voxelSpacing.annotations.flatMap( - (annotation) => annotation.object_name, - ), - ), - ), - ), - ), - [dataset.run_stats], + const objectNames = v2.annotationsAggregate.aggregate!.map( + (aggregate) => aggregate.groupBy!.objectName!, ) - const objectShapeTypes = useMemo( - () => - Array.from( - new Set( - dataset.run_stats.flatMap((run) => - run.tomogram_voxel_spacings.flatMap((voxelSpacing) => - voxelSpacing.annotations.flatMap((annotation) => - annotation.files.flatMap((file) => file.shape_type), - ), - ), - ), - ), - ), - [dataset.run_stats], + const objectShapeTypes = v2.annotationShapesAggregate.aggregate!.map( + (aggregate) => aggregate.groupBy!.shapeType!, ) return { From 2473e3029aa64ed5764afc516f4ae6184a276783 Mon Sep 17 00:00:00 2001 From: Jeremy Asuncion Date: Tue, 24 Dec 2024 12:14:24 -0800 Subject: [PATCH 17/35] test: unit tests feature components (#1423) * DepositionFilterBanner tests * InfoLink tests * MLChallengeBanner tests * ObjectIdLink tests * mock css modules * extract MLChallenge mock utils * SurveyBanner tests * TablePageLayout tests * fix remix mock types * add comments --- .../components/InfoLink/InfoLink.test.tsx | 80 +++++++++ .../components/InfoLink/InfoLink.tsx | 13 +- .../DepositionFilterBanner.test.tsx | 83 +++++++++ .../app/components/DepositionFilterBanner.tsx | 2 +- .../data-portal/app/components/I18n.mock.tsx | 17 ++ .../data-portal/app/components/I18n.tsx | 5 +- .../MLChallenge/MLChallengeBanner.test.tsx | 90 ++++++++++ .../ObjectIdLink/ObjectIdLink.test.tsx | 49 ++++++ .../SurveyBanner/SurveyBanner.test.tsx | 71 ++++++++ .../components/SurveyBanner/SurveyBanner.tsx | 7 +- .../TablePageLayout/TablePageLayout.test.tsx | 166 ++++++++++++++++++ .../data-portal/app/components/Tabs.tsx | 5 +- .../app/mocks/LocalStorage.mock.ts | 30 ++++ .../data-portal/app/mocks/Remix.mock.ts | 62 +++++++ .../packages/data-portal/app/utils/mock.ts | 18 ++ frontend/packages/data-portal/jest.config.cjs | 1 + frontend/packages/data-portal/package.json | 1 + frontend/pnpm-lock.yaml | 14 ++ 18 files changed, 699 insertions(+), 15 deletions(-) create mode 100644 frontend/packages/data-portal/app/components/Dataset/SampleAndExperimentConditionsTable/components/InfoLink/InfoLink.test.tsx create mode 100644 frontend/packages/data-portal/app/components/DepositionFilterBanner.test.tsx create mode 100644 frontend/packages/data-portal/app/components/I18n.mock.tsx create mode 100644 frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.test.tsx create mode 100644 frontend/packages/data-portal/app/components/Run/AnnotationObjectTable/components/ObjectIdLink/ObjectIdLink.test.tsx create mode 100644 frontend/packages/data-portal/app/components/SurveyBanner/SurveyBanner.test.tsx create mode 100644 frontend/packages/data-portal/app/components/TablePageLayout/TablePageLayout.test.tsx create mode 100644 frontend/packages/data-portal/app/mocks/LocalStorage.mock.ts create mode 100644 frontend/packages/data-portal/app/mocks/Remix.mock.ts create mode 100644 frontend/packages/data-portal/app/utils/mock.ts diff --git a/frontend/packages/data-portal/app/components/Dataset/SampleAndExperimentConditionsTable/components/InfoLink/InfoLink.test.tsx b/frontend/packages/data-portal/app/components/Dataset/SampleAndExperimentConditionsTable/components/InfoLink/InfoLink.test.tsx new file mode 100644 index 000000000..e2ab90e55 --- /dev/null +++ b/frontend/packages/data-portal/app/components/Dataset/SampleAndExperimentConditionsTable/components/InfoLink/InfoLink.test.tsx @@ -0,0 +1,80 @@ +import { createRemixStub } from '@remix-run/testing' +import { render, screen } from '@testing-library/react' + +import { NCBI, OBO, WORMBASE } from 'app/constants/datasetInfoLinks' + +import { InfoLinkProps } from './InfoLink' + +async function renderInfoLink({ id, value }: InfoLinkProps) { + const { InfoLink } = await import('./InfoLink') + + function InfoLinkWrapper() { + return + } + + const InfoLinkStub = createRemixStub([ + { + path: '/', + Component: InfoLinkWrapper, + }, + ]) + + render() +} + +describe('', () => { + it('should render placeholder if no value', async () => { + await renderInfoLink({ id: 123 }) + expect(screen.getByText('--')).toBeInTheDocument() + }) + + it('should render ncbi link', async () => { + const id = 123 + const value = 'value' + await renderInfoLink({ id, value }) + + const link = screen.queryByRole('link', { name: value }) + expect(link).toBeVisible() + expect(link).toHaveAttribute('href', `${NCBI}${id}`) + }) + + it('should render ncbi link with id prefix', async () => { + const rawId = 123 + const id = `NCBITaxon:${rawId}` + const value = 'value' + await renderInfoLink({ id, value }) + + const link = screen.queryByRole('link', { name: value }) + expect(link).toBeVisible() + expect(link).toHaveAttribute('href', `${NCBI}${rawId}`) + }) + + it('should render wormbase link', async () => { + const id = 'WBStrain12345678' + const value = 'value' + await renderInfoLink({ id, value }) + + const link = screen.queryByRole('link', { name: value }) + expect(link).toBeVisible() + expect(link).toHaveAttribute('href', `${WORMBASE}${id}`) + }) + + it('should render obo link', async () => { + const id = 'foobar:123' + const value = 'value' + await renderInfoLink({ id, value }) + + const link = screen.queryByRole('link', { name: value }) + expect(link).toBeVisible() + expect(link).toHaveAttribute('href', `${OBO}${id.replaceAll(':', '_')}`) + }) + + it('should not render link if no pattern match', async () => { + const id = 'someid123' + const value = 'value' + await renderInfoLink({ id, value }) + + expect(screen.queryByRole('link', { name: value })).not.toBeInTheDocument() + expect(screen.getByText(value)).toBeInTheDocument() + }) +}) diff --git a/frontend/packages/data-portal/app/components/Dataset/SampleAndExperimentConditionsTable/components/InfoLink/InfoLink.tsx b/frontend/packages/data-portal/app/components/Dataset/SampleAndExperimentConditionsTable/components/InfoLink/InfoLink.tsx index 647a3d8e8..271400c7a 100644 --- a/frontend/packages/data-portal/app/components/Dataset/SampleAndExperimentConditionsTable/components/InfoLink/InfoLink.tsx +++ b/frontend/packages/data-portal/app/components/Dataset/SampleAndExperimentConditionsTable/components/InfoLink/InfoLink.tsx @@ -8,13 +8,12 @@ import { WORMBASE_PATTERN, } from 'app/constants/datasetInfoLinks' -export function InfoLink({ - value, - id, -}: { +export interface InfoLinkProps { value?: string | null - id?: string | null -}) { + id?: number | string | null +} + +export function InfoLink({ value, id }: InfoLinkProps) { if (!value) { return -- } @@ -22,7 +21,7 @@ export function InfoLink({ if (id) { let link if (typeof id === 'number') { - link = `${NCBI}${id as number}` + link = `${NCBI}${id}` } else if (id.match(NCBI_ONTOLOGY_PATTERN)) { link = `${NCBI}${id.replace('NCBITaxon:', '')}` } else if (id.match(WORMBASE_PATTERN)) { diff --git a/frontend/packages/data-portal/app/components/DepositionFilterBanner.test.tsx b/frontend/packages/data-portal/app/components/DepositionFilterBanner.test.tsx new file mode 100644 index 000000000..7b2821261 --- /dev/null +++ b/frontend/packages/data-portal/app/components/DepositionFilterBanner.test.tsx @@ -0,0 +1,83 @@ +import { jest } from '@jest/globals' +import { createRemixStub } from '@remix-run/testing' +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' + +import { MockI18n } from './I18n.mock' + +const MOCK_DEPOSITION = { + id: 123, + title: 'Title', +} + +jest.unstable_mockModule('app/components/I18n', () => ({ + __esModule: true, + I18n: MockI18n, +})) + +const setDepositionIdMock = jest.fn() + +jest.unstable_mockModule('app/hooks/useQueryParam', () => ({ + useQueryParam: jest.fn().mockReturnValue([null, setDepositionIdMock]), +})) + +const setPreviousSingleDatasetParamsMock = jest.fn() + +jest.unstable_mockModule('app/state/filterHistory', () => ({ + useDepositionHistory: jest.fn(() => ({ + previousSingleDepositionParams: 'object=foo', + })), + + useSingleDatasetFilterHistory: jest.fn(() => ({ + previousSingleDatasetParams: `object=foo&deposition-id=${MOCK_DEPOSITION.id}`, + setPreviousSingleDatasetParams: setPreviousSingleDatasetParamsMock, + })), +})) + +async function renderDepositionFilterBanner() { + const { DepositionFilterBanner } = await import('./DepositionFilterBanner') + + function DepositionFilterBannerWrapper() { + return ( + + ) + } + + const DepositionFilterBannerStub = createRemixStub([ + { + path: '/', + Component: DepositionFilterBannerWrapper, + }, + ]) + + render() +} + +describe('', () => { + it('should render deposition url', async () => { + await renderDepositionFilterBanner() + + const text = screen.getByText('onlyDisplayingRunsWithAnnotations') + expect(text).toHaveAttribute( + 'data-values', + JSON.stringify({ + ...MOCK_DEPOSITION, + url: `/depositions/${MOCK_DEPOSITION.id}?object=foo`, + }), + ) + }) + + it('should remove filter on click', async () => { + await renderDepositionFilterBanner() + + await userEvent.click(screen.getByRole('button', { name: 'removeFilter' })) + + expect(setDepositionIdMock).toHaveBeenCalledWith(null) + expect(setPreviousSingleDatasetParamsMock).toHaveBeenCalledWith( + 'object=foo', + ) + }) +}) diff --git a/frontend/packages/data-portal/app/components/DepositionFilterBanner.tsx b/frontend/packages/data-portal/app/components/DepositionFilterBanner.tsx index 725a2fe26..0c73dc577 100644 --- a/frontend/packages/data-portal/app/components/DepositionFilterBanner.tsx +++ b/frontend/packages/data-portal/app/components/DepositionFilterBanner.tsx @@ -38,7 +38,7 @@ export function DepositionFilterBanner({ i18nKey={labelI18n} values={{ ...deposition, - url: `/depositions/${deposition.id}${previousSingleDepositionParams}`, + url: `/depositions/${deposition.id}?${previousSingleDepositionParams}`, }} tOptions={{ interpolation: { escapeValue: false } }} /> diff --git a/frontend/packages/data-portal/app/components/I18n.mock.tsx b/frontend/packages/data-portal/app/components/I18n.mock.tsx new file mode 100644 index 000000000..ccfe5fc34 --- /dev/null +++ b/frontend/packages/data-portal/app/components/I18n.mock.tsx @@ -0,0 +1,17 @@ +import type { I18nProps } from './I18n' + +/** + * Mock I18n component for rendering span element with i18n key as the content. + * Any values are passed in the data-attribute prop in case values need to be + * tested. + */ +export function MockI18n({ i18nKey, values, linkProps }: I18nProps) { + return ( + + {i18nKey} + + ) +} diff --git a/frontend/packages/data-portal/app/components/I18n.tsx b/frontend/packages/data-portal/app/components/I18n.tsx index 3c475a55a..1e640547c 100644 --- a/frontend/packages/data-portal/app/components/I18n.tsx +++ b/frontend/packages/data-portal/app/components/I18n.tsx @@ -5,7 +5,8 @@ import type { I18nKeys } from 'app/types/i18n' import { Link, VariantLinkProps } from './Link' -interface Props extends Omit, 'ns' | 'i18nKey'> { +export interface I18nProps + extends Omit, 'ns' | 'i18nKey'> { i18nKey: I18nKeys linkProps?: Partial } @@ -14,7 +15,7 @@ interface Props extends Omit, 'ns' | 'i18nKey'> { * Wrapper over `Trans` component with strong typing support for i18n keys. It * also includes a few default components for rendering inline JSX. */ -export function I18n({ i18nKey, components, linkProps, ...props }: Props) { +export function I18n({ i18nKey, components, linkProps, ...props }: I18nProps) { return ( ) +} + +jest.unstable_mockModule('app/components/I18n', () => ({ I18n: MockI18n })) + +const remixMock = new RemixMock() +const localStorageMock = new LocalStorageMock() + +describe('', () => { + beforeEach(() => { + jest.useRealTimers() + localStorageMock.reset() + remixMock.reset() + }) + + const paths = ['/', '/browse-data/datasets', '/browse-data/depositions'] + + paths.forEach((pathname) => { + it(`should render on ${pathname}`, async () => { + remixMock.mockPathname(pathname) + await renderMlChallengeBanner() + expect(screen.queryByRole('banner')).toBeVisible() + }) + }) + + it('should not render on blocked pages', async () => { + remixMock.mockPathname('/competition') + await renderMlChallengeBanner() + expect(screen.queryByRole('banner')).not.toBeInTheDocument() + }) + + it('should render challenge began message', async () => { + setMockTime('2024-12-01') + + await renderMlChallengeBanner() + expect(screen.getByText('mlCompetitionHasBegun')).toBeVisible() + }) + + it('should render challenge ending message', async () => { + setMockTime('2025-01-30') + + await renderMlChallengeBanner() + expect(screen.getByText('mlCompetitionEnding')).toBeVisible() + }) + + it('should render challenge ended message', async () => { + setMockTime('2025-02-07') + + await renderMlChallengeBanner() + expect(screen.getByText('mlCompetitionEnded')).toBeVisible() + }) + + it('should not render banner if was dismissed', async () => { + setMockTime('2024-12-01') + localStorageMock.mockValue('mlCompetitionHasBegun') + + await renderMlChallengeBanner() + expect(screen.queryByRole('banner')).not.toBeInTheDocument() + }) + + it('should render banner if last dismissed was previous state', async () => { + setMockTime('2025-01-30') + localStorageMock.mockValue('mlCompetitionHasBegun') + + await renderMlChallengeBanner() + expect(screen.getByRole('banner')).toBeVisible() + }) + + it('should dismiss banner on click', async () => { + setMockTime('2024-12-01') + + await renderMlChallengeBanner() + await getMockUser().click(screen.getByRole('button')) + + expect(screen.queryByRole('banner')).not.toBeInTheDocument() + expect(localStorageMock.setValue).toHaveBeenCalledWith( + 'mlCompetitionHasBegun', + ) + }) +}) diff --git a/frontend/packages/data-portal/app/components/Run/AnnotationObjectTable/components/ObjectIdLink/ObjectIdLink.test.tsx b/frontend/packages/data-portal/app/components/Run/AnnotationObjectTable/components/ObjectIdLink/ObjectIdLink.test.tsx new file mode 100644 index 000000000..db9f78406 --- /dev/null +++ b/frontend/packages/data-portal/app/components/Run/AnnotationObjectTable/components/ObjectIdLink/ObjectIdLink.test.tsx @@ -0,0 +1,49 @@ +import { createRemixStub } from '@remix-run/testing' +import { render, screen } from '@testing-library/react' + +import { GO, UNIPROTKB } from 'app/constants/annotationObjectIdLinks' + +async function renderObjectIdLink(id: string) { + const { ObjectIdLink } = await import('./ObjectIdLink') + + function ObjectIdLinkWrapper() { + return + } + + const ObjectIdLinkStub = createRemixStub([ + { + path: '/', + Component: ObjectIdLinkWrapper, + }, + ]) + + render() +} + +describe('', () => { + it('should render go link', async () => { + const id = 'GO:123' + await renderObjectIdLink(id) + + expect(screen.getByRole('link')).toHaveAttribute('href', `${GO}${id}`) + }) + + it('should render UniProtKB link', async () => { + const rawId = 123 + const id = `UniProtKB:${rawId}` + await renderObjectIdLink(id) + + expect(screen.getByRole('link')).toHaveAttribute( + 'href', + `${UNIPROTKB}${rawId}`, + ) + }) + + it('should not render link if not matched', async () => { + const id = 'test-id-123' + await renderObjectIdLink(id) + + expect(screen.queryByRole('link')).not.toBeInTheDocument() + expect(screen.getByText(id)).toBeVisible() + }) +}) diff --git a/frontend/packages/data-portal/app/components/SurveyBanner/SurveyBanner.test.tsx b/frontend/packages/data-portal/app/components/SurveyBanner/SurveyBanner.test.tsx new file mode 100644 index 000000000..a8aee296c --- /dev/null +++ b/frontend/packages/data-portal/app/components/SurveyBanner/SurveyBanner.test.tsx @@ -0,0 +1,71 @@ +import { beforeEach, jest } from '@jest/globals' +import { render, screen } from '@testing-library/react' + +import { MockI18n } from 'app/components/I18n.mock' +import { LocalStorageMock } from 'app/mocks/LocalStorage.mock' +import { RemixMock } from 'app/mocks/Remix.mock' +import { getMockUser, setMockTime } from 'app/utils/mock' + +async function renderSurveyBanner() { + const { SurveyBanner } = await import('./SurveyBanner') + render() +} + +jest.unstable_mockModule('app/components/I18n', () => ({ I18n: MockI18n })) + +const remixMock = new RemixMock() +const localStorageMock = new LocalStorageMock() + +describe('', () => { + beforeEach(() => { + jest.useRealTimers() + remixMock.reset() + remixMock.mockPathname('/datasets/123') + localStorageMock.reset() + }) + + const pages = ['/datasets/123', '/runs/123', '/depositions/123'] + + pages.forEach((pathname) => { + it(`should render on ${pathname}`, async () => { + remixMock.mockPathname(pathname) + await renderSurveyBanner() + expect(screen.queryByRole('banner')).toBeVisible() + }) + }) + + it('should not render on blocked pages', async () => { + remixMock.mockPathname('/') + await renderSurveyBanner() + expect(screen.queryByRole('banner')).not.toBeInTheDocument() + }) + + it('should dismiss on click', async () => { + const time = '2024-12-01' + setMockTime(time) + + await renderSurveyBanner() + await getMockUser().click(screen.getByRole('button')) + + expect(screen.queryByRole('banner')).not.toBeInTheDocument() + expect(localStorageMock.setValue).toHaveBeenCalledWith( + new Date(time).toISOString(), + ) + }) + + it('should not render banner if previously dismissed', async () => { + setMockTime('2024-12-01') + localStorageMock.mockValue(new Date('2024-11-25').toISOString()) + + await renderSurveyBanner() + expect(screen.queryByRole('banner')).not.toBeInTheDocument() + }) + + it('should render banner if dismissed >= 2 weeks ago', async () => { + setMockTime('2024-12-01') + localStorageMock.mockValue(new Date('2024-10-30').toISOString()) + + await renderSurveyBanner() + expect(screen.queryByRole('banner')).toBeVisible() + }) +}) diff --git a/frontend/packages/data-portal/app/components/SurveyBanner/SurveyBanner.tsx b/frontend/packages/data-portal/app/components/SurveyBanner/SurveyBanner.tsx index df003e81c..673a0a616 100644 --- a/frontend/packages/data-portal/app/components/SurveyBanner/SurveyBanner.tsx +++ b/frontend/packages/data-portal/app/components/SurveyBanner/SurveyBanner.tsx @@ -42,14 +42,15 @@ export function SurveyBanner() { const location = useLocation() + if (!BANNER_ALLOWLIST.some((regex) => regex.test(location.pathname))) { + return null + } + return (

X<*kBlZy>=C!&6WPl2SCkq4S1x_V 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