Skip to content

Commit

Permalink
PORTALS-3373: in progress, portal does not currently start
Browse files Browse the repository at this point in the history
  • Loading branch information
jay-hodgson committed Jan 10, 2025
1 parent 4431e59 commit 65cb3ca
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 12 deletions.
6 changes: 6 additions & 0 deletions apps/portals/cancercomplexity/src/config/routesConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
onIndividualThemeBarPlotPointClick,
onPointClick,
} from './synapseConfigs/onPointClick'
import { CCKPSearchPage, searchPageChildRoutes } from 'src/pages/CCKPSearchPage'

const routes: RouteObject[] = [
{
Expand Down Expand Up @@ -235,6 +236,11 @@ const routes: RouteObject[] = [
path: 'MC2Supplement',
element: <MC2Supplement />,
},
{
path: 'Search',
element: <CCKPSearchPage />,
children: searchPageChildRoutes,
},
],
},
]
Expand Down
43 changes: 43 additions & 0 deletions apps/portals/cancercomplexity/src/pages/CCKPSearchPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
PortalSearchTabConfig,
PortalSearchTabs,
} from '@sage-bionetworks/synapse-portal-framework/components/PortalSearch/PortalSearchTabs'
import { PortalFullTextSearchField } from '@sage-bionetworks/synapse-portal-framework/components/PortalSearch/PortalFullTextSearchField'

import RedirectWithQuery from '@sage-bionetworks/synapse-portal-framework/components/RedirectWithQuery'
import { useGetPortalComponentSearchParams } from '@sage-bionetworks/synapse-portal-framework/utils/UseGetPortalComponentSearchParams'
import { Outlet, RouteObject } from 'react-router-dom'
import { grantQueryWrapperPlotNavProps } from 'src/config/synapseConfigs/grants'
import { QueryWrapperPlotNav } from 'synapse-react-client'
export const searchPageTabs: PortalSearchTabConfig[] = [
{
title: 'Grants',
path: 'Grants',
tooltip: 'Search Grants',
},
]

export const searchPageChildRoutes: RouteObject[] = [
{
index: true,
element: <RedirectWithQuery to={searchPageTabs[0].path} />,
},
{
path: searchPageTabs[0].path,
element: <QueryWrapperPlotNav {...grantQueryWrapperPlotNavProps} />,
},
]

export function CCKPSearchPage(props: React.PropsWithChildren) {
const { children } = props
const searchParams = useGetPortalComponentSearchParams()
// on search field value update, update the special search parameter FTS_SEARCH_TERM, which the QueryWrapperPlotNav will load as the search term
return (
<>
<PortalFullTextSearchField />
<PortalSearchTabs tabConfig={searchPageTabs} />
{children}
<Outlet />
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useState } from 'react'
import SearchIcon from '@mui/icons-material/Search'
import { InputAdornment, TextField } from '@mui/material'
import { useSearchParams } from 'react-router-dom'
import { FTS_SEARCH_PARAM_KEY } from 'synapse-react-client/utils/functions/SqlFunctions'

export function PortalFullTextSearchField() {
const [searchParams, setSearchParams] = useSearchParams()
const [searchInput, setSearchInput] = useState(
searchParams.get(FTS_SEARCH_PARAM_KEY),
)

return (
<TextField
size={'small'}
placeholder="Search by keyword"
value={searchInput}
onChange={event => {
setSearchInput(event.target.value)
}}
onKeyDown={(event: any) => {
if (event.key === 'Enter') {
const trimmedInput = event.target.value.trim()
setSearchParams({ FTS_SEARCH_PARAM_KEY: trimmedInput })
}
}}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
sx={{
maxWidth: { xs: '100%', md: '350px' },
flex: '1 1 350px',
}}
/>
)
}

export default PortalFullTextSearchField
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Tooltip, Chip } from '@mui/material'
import { NavLink, useLocation } from 'react-router-dom'

export type PortalSearchTabConfig = {
path: string
title: string
tooltip?: string
count?: number
}

export type PortalSearchTabUIProps = {
tabConfig: PortalSearchTabConfig[]
}

function PortalSearchTab(props: PortalSearchTabConfig) {
const { path, title, tooltip, count } = props
const location = useLocation()

return (
<Tooltip key={path} title={tooltip ?? ''} placement="top">
<NavLink
to={{
pathname: path,
search: location.search,
}}
className={'tab-item ignoreLink'}
>
{title}
{count !== undefined && (
<Chip
size={'small'}
label={count}
sx={{
backgroundColor: 'tertiary.500',
color: 'grey.900',
height: '21px',
}}
></Chip>
)}
</NavLink>
</Tooltip>
)
}

export function PortalSearchTabs(props: PortalSearchTabUIProps) {
const { tabConfig } = props

return (
<div className="tab-groups">
{tabConfig.map(config => (
<PortalSearchTab key={config.path} {...config} />
))}
</div>
)
}
4 changes: 4 additions & 0 deletions apps/synapse-portal-framework/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import Image from './Image'
import RedirectWithQuery from './RedirectWithQuery'
import RedirectToURL from './RedirectToURL'
import { Navigate as Redirect } from 'react-router-dom'
import { PortalSearchTabs } from './PortalSearch/PortalSearchTabs'
import { PortalFullTextSearchField } from './PortalSearch/PortalFullTextSearchField'
import Header from './Header'
import ChallengeParticipantGoogleMap from './challengeportal/ChallengeParticipantGoogleMap'
import ChallengeDetailPageWrapper from './challengeportal/ChallengeDetailPageWrapper'
Expand Down Expand Up @@ -60,6 +62,8 @@ const PortalComponents = {
ChallengeDataDownloadWrapper,
SynapseComponentCollapse: ComponentCollapse,
SurveyToast,
PortalSearchTabs,
PortalFullTextSearchField,
}

export default PortalComponents
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,30 @@ function QueryWrapperPlotNavContents(props: QueryWrapperPlotNavContentsProps) {
)
}

export const getQueryRequest = ({
entityId,
query,
}: {
entityId: string
query: Query
}) => {
const request: QueryBundleRequest = {
entityId,
concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',
partMask:
SynapseConstants.BUNDLE_MASK_QUERY_RESULTS |
SynapseConstants.BUNDLE_MASK_QUERY_COUNT |
SynapseConstants.BUNDLE_MASK_QUERY_SELECT_COLUMNS |
SynapseConstants.BUNDLE_MASK_QUERY_MAX_ROWS_PER_PAGE |
SynapseConstants.BUNDLE_MASK_QUERY_COLUMN_MODELS |
SynapseConstants.BUNDLE_MASK_QUERY_FACETS |
SynapseConstants.BUNDLE_MASK_SUM_FILES_SIZE_BYTES |
SynapseConstants.BUNDLE_MASK_LAST_UPDATED_ON,
query,
}
return request
}

function QueryWrapperPlotNav(props: QueryWrapperPlotNavProps) {
const {
searchParams,
Expand Down Expand Up @@ -312,20 +336,10 @@ function QueryWrapperPlotNav(props: QueryWrapperPlotNavProps) {
}

const { data: entity } = useGetEntity(entityId, versionNumber)
const initQueryRequest: QueryBundleRequest = {
const initQueryRequest: QueryBundleRequest = getQueryRequest({
entityId,
concreteType: 'org.sagebionetworks.repo.model.table.QueryBundleRequest',
partMask:
SynapseConstants.BUNDLE_MASK_QUERY_RESULTS |
SynapseConstants.BUNDLE_MASK_QUERY_COUNT |
SynapseConstants.BUNDLE_MASK_QUERY_SELECT_COLUMNS |
SynapseConstants.BUNDLE_MASK_QUERY_MAX_ROWS_PER_PAGE |
SynapseConstants.BUNDLE_MASK_QUERY_COLUMN_MODELS |
SynapseConstants.BUNDLE_MASK_QUERY_FACETS |
SynapseConstants.BUNDLE_MASK_SUM_FILES_SIZE_BYTES |
SynapseConstants.BUNDLE_MASK_LAST_UPDATED_ON,
query,
}
})
const isFullTextSearchEnabled =
(entity && isTable(entity) && entity.isSearchEnabled) ?? false

Expand Down
13 changes: 13 additions & 0 deletions packages/synapse-react-client/src/utils/functions/SqlFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
QueryFilter,
Row,
SelectColumn,
TextMatchesQueryFilter,
} from '@sage-bionetworks/synapse-types'
import { SYNAPSE_ENTITY_ID_REGEX } from './RegularExpressions'

Expand All @@ -29,6 +30,10 @@ export const getIgnoredQueryFilterSearchParamKey = (
) => {
return `__${namespace ?? ''}_${key}`
}

// Special search parameter key that will automatically apply a FTS search term to a Query Wrapper if present
export const FTS_SEARCH_PARAM_KEY = 'FTS_SEARCH_TERM'

/**
* Look in local storage for a set of QueryFilters to apply. In addition, given the search params,
* generate a set of QueryFilters to narrow the the query to view just related data.
Expand Down Expand Up @@ -61,6 +66,14 @@ export const getAdditionalFilters = (
Object.keys(searchParams || {})
.filter(key => !isQueryWrapperKey(key))
.map(key => {
if (key == FTS_SEARCH_PARAM_KEY) {
const filter: TextMatchesQueryFilter = {
concreteType:
'org.sagebionetworks.repo.model.table.TextMatchesQueryFilter',
searchExpression: searchParams[key],
}
return filter
}
switch (operator) {
case ColumnSingleValueFilterOperator.EQUAL: {
const filter: ColumnSingleValueQueryFilter = {
Expand Down

0 comments on commit 65cb3ca

Please sign in to comment.