diff --git a/api/routes/web.py b/api/routes/web.py
index d07ffc2ec..38255514b 100644
--- a/api/routes/web.py
+++ b/api/routes/web.py
@@ -81,11 +81,18 @@ async def search_by_keyword(keyword: str, connection=get_projectless_db_connecti
projects = await pt.get_projects_accessible_by_user(
connection.author, readonly=True
)
- project_ids = [p.id for p in projects]
- responses = await SearchLayer(connection).search(keyword, project_ids=project_ids)
+ pmap = {p.id: p for p in projects}
+ responses = await SearchLayer(connection).search(
+ keyword, project_ids=list(pmap.keys())
+ )
for res in responses:
- res.data.project = projects.get(res.data.project, res.data.project) # type: ignore
+ if res.data.project in pmap:
+ # the solution to the type issue is to create internal / external models
+ # and convert between them for transport
+ res.data.project = pmap[res.data.project].name # type: ignore
+ else:
+ res.data.project = str(res.data.project)
return SearchResponseModel(responses=responses)
diff --git a/web/src/shared/components/Header/Search.tsx b/web/src/shared/components/Header/Search.tsx
index e8fa09ab0..a481ca0f3 100644
--- a/web/src/shared/components/Header/Search.tsx
+++ b/web/src/shared/components/Header/Search.tsx
@@ -72,12 +72,15 @@ const SearchReducer = (state: State, action: Action): State => {
}
}
-const resultRenderer = ({ ...props }) => {
+const resultRenderer = ({ data, ...props }) => {
let components = []
let icon: React.ReactElement = <>>
let available: string | undefined
let colour = 'black'
- if (!props.data.id) {
+ if (!data) {
+ return An error occurred when rendering search results
+ }
+ if (!data?.id) {
available = `No access to this ${props.type}`
colour = 'gray'
}
@@ -89,27 +92,27 @@ const resultRenderer = ({ ...props }) => {
switch (props.type) {
case SearchResponseType.Sample: {
- components.push(...(props.data.sample_external_ids || []))
+ components.push(...(data.sample_external_ids || []))
icon =
break
}
case SearchResponseType.Participant: {
- components.push(...(props.data.participant_external_ids || []))
+ components.push(...(data.participant_external_ids || []))
icon =
break
}
case SearchResponseType.Family: {
- components.push(...(props.data.family_external_ids || []))
+ components.push(...(data.family_external_ids || []))
icon =
break
}
case SearchResponseType.SequencingGroup: {
- components.push(...(props.data.sample_external_ids || []))
+ components.push(...(data.sample_external_ids || []))
icon =
break
}
case SearchResponseType.Error: {
- components.push(props.data.error)
+ components.push(data?.error)
icon =
break
}
@@ -120,7 +123,7 @@ const resultRenderer = ({ ...props }) => {
const subtitle = components.length > 0 ? components.join(' ยท ') : null
- const key = String(props.data.id || `${props.data.project}|${props.data.title}`)
+ const key = String(data.id || `${data.project}|${data.title}`)
// prefer early return for empty results
if (!props.title || !props.type) return <>>
@@ -148,7 +151,7 @@ const resultRenderer = ({ ...props }) => {
fontStyle: 'italic',
}}
>
- {props.data.project}
+ {data.project}
@@ -227,7 +230,10 @@ const Searchbar: React.FunctionComponent = () => {
{
title: 'Error',
type: 'error',
- error: { error: er.message },
+ data: {
+ id: '#error',
+ error: er.response?.data?.description || er.message,
+ },
},
] as SearchResponse[],
query: '',