-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Orthogroup tree table 1254 fixes #1259
Changes from 14 commits
5e04a76
bbd65ea
564f453
6907790
494e55d
25def36
075fff3
0c382ac
997837d
2e76120
6b8f7f4
5deced2
4557b84
2fa75aa
7ef7b0e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ import React, { | |
import TreeTable from '@veupathdb/components/lib/components/tidytree/TreeTable'; | ||
import { RecordTableProps, WrappedComponentProps } from './Types'; | ||
import { useOrthoService } from 'ortho-client/hooks/orthoService'; | ||
import { Loading } from '@veupathdb/wdk-client/lib/Components'; | ||
import { Loading, Link } from '@veupathdb/wdk-client/lib/Components'; | ||
import { Branch, parseNewick } from 'patristic'; | ||
import { | ||
AttributeValue, | ||
|
@@ -39,6 +39,10 @@ import { | |
import { RecordTable_TaxonCounts_Filter } from './RecordTable_TaxonCounts_Filter'; | ||
import { formatAttributeValue } from '@veupathdb/wdk-client/lib/Utils/ComponentUtils'; | ||
import { RecordFilter } from '@veupathdb/wdk-client/lib/Views/Records/RecordTable/RecordFilter'; | ||
import { | ||
areTermsInStringRegexString, | ||
parseSearchQueryString, | ||
} from '@veupathdb/wdk-client/lib/Utils/SearchUtils'; | ||
|
||
type RowType = Record<string, AttributeValue>; | ||
|
||
|
@@ -94,7 +98,10 @@ export function RecordTable_Sequences( | |
const numSequences = mesaRows.length; | ||
|
||
const treeResponse = useOrthoService( | ||
(orthoService) => orthoService.getGroupTree(groupName), | ||
(orthoService) => { | ||
if (numSequences < 3) return Promise.resolve(undefined); | ||
return orthoService.getGroupTree(groupName); | ||
}, | ||
[groupName, numSequences] | ||
); | ||
|
||
|
@@ -191,7 +198,7 @@ export function RecordTable_Sequences( | |
const { tree, leaves, sortedRows } = useMemo(() => { | ||
const tree = treeResponse == null ? undefined : parseNewick(treeResponse); | ||
const leaves = tree && getLeaves(tree); | ||
const sortedRows = leaves && sortRows(leaves, mesaRows); | ||
const sortedRows = leaves ? sortRows(leaves, mesaRows) : mesaRows; | ||
return { tree, leaves, sortedRows }; | ||
}, [treeResponse, mesaRows]); | ||
|
||
|
@@ -391,20 +398,16 @@ export function RecordTable_Sequences( | |
|
||
// None shall pass! (hooks, at least) | ||
|
||
if ( | ||
!mesaState || | ||
!sortedRows || | ||
(numSequences >= MIN_SEQUENCES_FOR_TREE && | ||
numSequences <= MAX_SEQUENCES_FOR_TREE && | ||
(tree == null || treeResponse == null)) | ||
) { | ||
if (!mesaState || !sortedRows || !tree || !treeResponse) { | ||
return <Loading />; | ||
} | ||
|
||
if ( | ||
numSequences >= 3 && | ||
mesaRows != null && | ||
sortedRows != null && | ||
mesaRows.length !== sortedRows.length | ||
(mesaRows.length !== sortedRows.length || | ||
mesaRows.length !== leaves?.length) | ||
Comment on lines
+410
to
+411
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are both comparisons necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I think so.
Just using |
||
) { | ||
console.log( | ||
'Tree and protein list mismatch. A=Tree, B=Table. Summary below:' | ||
|
@@ -419,8 +422,16 @@ export function RecordTable_Sequences( | |
<Banner | ||
banner={{ | ||
type: 'warning', | ||
message: | ||
'Tree and protein list mismatch. Please contact the helpdesk', | ||
message: ( | ||
<span> | ||
A data processing error has occurred on our end. We apologize for | ||
the inconvenience. If this problem persists, please{' '} | ||
<Link target="_blank" to="/contact-us"> | ||
contact us | ||
</Link> | ||
. | ||
</span> | ||
), | ||
}} | ||
/> | ||
); | ||
|
@@ -514,6 +525,7 @@ export function RecordTable_Sequences( | |
onPress={() => { | ||
proteinFilterButtonRef.current?.close(); | ||
setProteinFilterIds([]); | ||
setTablePageNumber(1); | ||
}} | ||
/> | ||
); | ||
|
@@ -522,6 +534,7 @@ export function RecordTable_Sequences( | |
proteinFilterButtonRef.current?.close(); | ||
setProteinFilterIds(highlightedNodes); | ||
setHighlightedNodes([]); | ||
setTablePageNumber(1); | ||
}; | ||
|
||
const proteinFilter = ( | ||
|
@@ -604,12 +617,13 @@ export function RecordTable_Sequences( | |
corePeripheralFilterValue.length + | ||
selectedSpecies.length + | ||
proteinFilterIds.length === | ||
0 | ||
0 && searchQuery === '' | ||
} | ||
icon={Undo} | ||
size={'medium'} | ||
themeRole={'primary'} | ||
onPress={() => { | ||
setSearchQuery(''); | ||
setProteinFilterIds([]); | ||
setPfamFilterIds([]); | ||
setCorePeripheralFilterValue([]); | ||
|
@@ -622,6 +636,23 @@ export function RecordTable_Sequences( | |
|
||
if (filteredRows == null) return null; | ||
|
||
const warningText = | ||
numSequences >= 3 && | ||
(filteredRows.length > MAX_SEQUENCES_FOR_TREE || | ||
filteredRows.length < MIN_SEQUENCES_FOR_TREE) ? ( | ||
<span> | ||
To see a phylogenetic tree please use a filter to display between{' '} | ||
{MIN_SEQUENCES_FOR_TREE.toLocaleString()} and{' '} | ||
{MAX_SEQUENCES_FOR_TREE.toLocaleString()} sequences | ||
</span> | ||
) : filteredRows.length < sortedRows.length ? ( | ||
<span> | ||
Note: The ortholog group's phylogeny has been pruned to display only the | ||
currently filtered proteins. This may differ from a tree constructed{' '} | ||
<i>de novo</i> using only these sequences. | ||
</span> | ||
) : undefined; | ||
|
||
return ( | ||
<div | ||
style={ | ||
|
@@ -630,8 +661,7 @@ export function RecordTable_Sequences( | |
} as CSSProperties | ||
} | ||
> | ||
{(filteredRows.length > MAX_SEQUENCES_FOR_TREE || | ||
filteredRows.length < MIN_SEQUENCES_FOR_TREE) && ( | ||
{warningText && ( | ||
<div | ||
style={{ | ||
display: 'flex', | ||
|
@@ -645,9 +675,7 @@ export function RecordTable_Sequences( | |
fontWeight: 500, | ||
}} | ||
> | ||
To see a phylogenetic tree please use a filter to display between{' '} | ||
{MIN_SEQUENCES_FOR_TREE.toLocaleString()} and{' '} | ||
{MAX_SEQUENCES_FOR_TREE.toLocaleString()} sequences | ||
{warningText} | ||
</div> | ||
)} | ||
<div | ||
|
@@ -662,6 +690,7 @@ export function RecordTable_Sequences( | |
}} | ||
> | ||
<RecordFilter | ||
key={`text-search-${resetCounter}`} | ||
searchTerm={searchQuery} | ||
onSearchTermChange={setSearchQuery} | ||
recordDisplayName="Proteins" | ||
|
@@ -781,14 +810,9 @@ function rowMatch(row: RowType, query: RegExp, keys?: string[]): boolean { | |
|
||
function createSafeSearchRegExp(input: string): RegExp | undefined { | ||
if (input === '') return undefined; | ||
try { | ||
// Attempt to create a RegExp from the user input directly | ||
return new RegExp(input, 'i'); | ||
} catch (error) { | ||
// If an error occurs (e.g., invalid RegExp), escape the input and create a literal search RegExp | ||
const escapedInput = input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); | ||
return new RegExp(escapedInput, 'i'); | ||
} | ||
const queryTerms = parseSearchQueryString(input); | ||
const searchTermRegex = areTermsInStringRegexString(queryTerms); | ||
return new RegExp(searchTermRegex, 'i'); | ||
} | ||
|
||
function logIdMismatches(A: string[], B: string[]) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably use
MIN_SEQUENCES_FOR_TREE
here.