-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Nickakhmetov/HMP-389 Fix autocomplete selection behavior (#3252)
* Prevent already-selected options from being suggested by autocomplete component * Fix "getOptionLabel returned undefined" errors in console * supress "invalid value" warning when selected genes are no longer in options list * Convert `AutocompleteEntity` to TypeScript * Fix alignment of genomic modality select dropdown * prettier fix
- Loading branch information
1 parent
b1683d2
commit 49a5971
Showing
7 changed files
with
122 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
- Prevent already-selected options from being suggested by autocomplete component. |
92 changes: 0 additions & 92 deletions
92
context/app/static/js/components/cells/AutocompleteEntity/AutocompleteEntity.jsx
This file was deleted.
Oops, something went wrong.
87 changes: 87 additions & 0 deletions
87
context/app/static/js/components/cells/AutocompleteEntity/AutocompleteEntity.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import React, { useState, useEffect } from 'react'; | ||
|
||
import Autocomplete from '@mui/material/Autocomplete'; | ||
import TextField, { TextFieldProps } from '@mui/material/TextField'; | ||
import Chip from '@mui/material/Chip'; | ||
import { useAutocompleteQuery } from './hooks'; | ||
import { AutocompleteQueryResponse } from './types'; | ||
|
||
function buildHelperText(entity: string): string { | ||
return `Multiple ${entity} are allowed and only 'AND' queries are supported.`; | ||
} | ||
|
||
const labelAndHelperTextProps: Record<string, Pick<TextFieldProps, 'label' | 'helperText'>> = { | ||
genes: { label: 'Gene Symbol', helperText: buildHelperText('gene symbols') }, | ||
proteins: { label: 'Protein', helperText: buildHelperText('proteins') }, | ||
}; | ||
|
||
type AutocompleteEntityProps = { | ||
targetEntity: string; | ||
setter: (value: string[]) => void; | ||
}; | ||
|
||
function AutocompleteEntity({ targetEntity, setter }: AutocompleteEntityProps) { | ||
const [substring, setSubstring] = useState(''); | ||
const [selectedOptions, setSelectedOptions] = useState<AutocompleteQueryResponse>([]); | ||
|
||
useEffect(() => { | ||
// Unwrap selected options and pass to setter to keep values in sync | ||
setter(selectedOptions.map((match) => match.full)); | ||
}, [selectedOptions, setter]); | ||
|
||
useEffect(() => { | ||
// Reset selected options and substring when target entity changes | ||
setSubstring(''); | ||
setSelectedOptions([]); | ||
}, [targetEntity]); | ||
|
||
const { data, isLoading } = useAutocompleteQuery({ targetEntity, substring }); | ||
|
||
// Include currently selected options to avoid invalid value errors in console | ||
const options = selectedOptions.concat(data || []); | ||
|
||
function handleChange({ target: { value } }: React.ChangeEvent<HTMLInputElement>) { | ||
setSubstring(value); | ||
} | ||
|
||
return ( | ||
<Autocomplete | ||
value={selectedOptions} | ||
options={options} | ||
multiple | ||
filterSelectedOptions | ||
getOptionLabel={(option) => option.full} | ||
isOptionEqualToValue={(option, value) => option.full === value.full} | ||
loading={isLoading} | ||
renderOption={(props, option) => ( | ||
<li {...props}> | ||
{option.pre} | ||
<b>{option.match}</b> | ||
{option.post} | ||
</li> | ||
)} | ||
renderTags={(value, getTagProps) => | ||
value.map((option, index) => { | ||
return <Chip label={option.full} {...getTagProps({ index })} key={option.full} />; | ||
}) | ||
} | ||
onChange={(_, value) => { | ||
setSelectedOptions(value); | ||
}} | ||
renderInput={({ InputLabelProps, ...params }) => ( | ||
<TextField | ||
InputLabelProps={{ shrink: true, ...InputLabelProps }} | ||
{...labelAndHelperTextProps[targetEntity]} | ||
placeholder={`Select ${targetEntity} to query`} | ||
value={substring} | ||
name="substring" | ||
variant="outlined" | ||
onChange={handleChange} | ||
{...params} | ||
/> | ||
)} | ||
/> | ||
); | ||
} | ||
|
||
export default AutocompleteEntity; |
19 changes: 19 additions & 0 deletions
19
context/app/static/js/components/cells/AutocompleteEntity/hooks.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import useSWR from 'swr'; | ||
import CellsService from '../CellsService'; | ||
import type { AutocompleteQueryKey, AutocompleteQueryResponse } from './types'; | ||
|
||
const cellsService = new CellsService(); | ||
|
||
const cellsServiceFetcher = async ({ | ||
targetEntity, | ||
substring, | ||
}: AutocompleteQueryKey): Promise<AutocompleteQueryResponse> => { | ||
if (!substring) { | ||
return []; | ||
} | ||
return cellsService.searchBySubstring({ targetEntity, substring }); | ||
}; | ||
|
||
export function useAutocompleteQuery(queryKey: AutocompleteQueryKey) { | ||
return useSWR<AutocompleteQueryResponse, Error>(queryKey, cellsServiceFetcher); | ||
} |
File renamed without changes.
13 changes: 13 additions & 0 deletions
13
context/app/static/js/components/cells/AutocompleteEntity/types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export interface AutocompleteQueryKey { | ||
targetEntity: string; | ||
substring: string; | ||
} | ||
|
||
export interface AutocompleteResult { | ||
match: string; | ||
full: string; | ||
pre: string; | ||
post: string; | ||
} | ||
|
||
export type AutocompleteQueryResponse = AutocompleteResult[]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters