Skip to content

Commit 4c809b4

Browse files
committed
Merge branch 'discvr-23.7' of https://github.com/BimberLab/DiscvrLabKeyModules into discvr-23.7
2 parents dedf0f9 + 207bb84 commit 4c809b4

File tree

7 files changed

+105
-34
lines changed

7 files changed

+105
-34
lines changed

jbrowse/src/client/JBrowse/Browser/plugins/ExtendedVariantPlugin/ExtendedVariantDisplay/model.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ export default jbrowse => {
217217
const region = view.getSelectedRegions(undefined, undefined)[0]
218218
const location = region.refName + ':' + (1+region.start) + '..' + (1+region.end)
219219
const sessionId = view.id;
220-
navigateToSearch(sessionId, location, track.configuration.trackId, track)
220+
navigateToSearch(sessionId, location, track.configuration.trackId, null, track)
221221
}
222222
})
223223
}

jbrowse/src/client/JBrowse/VariantSearch/VariantTable.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import VariantTableWidget from './components/VariantTableWidget';
1212
import { fetchSession } from '../utils';
1313
import { ErrorBoundary } from './components/ErrorBoundary';
1414
import LoadingIndicator from './components/LoadingIndicator';
15+
import deepmerge from '@mui/utils/deepmerge';
1516

1617
const nativePlugins = [ExtendedVariantPlugin, LogSession]
1718

@@ -21,6 +22,18 @@ function VariantTable() {
2122
const locString = queryParam.get('location') || queryParam.get('loc')
2223
const refTheme = createTheme()
2324

25+
const themeAdditions = {
26+
components: {
27+
MuiTooltip: {
28+
styleOverrides: {
29+
tooltip: {
30+
fontSize: '0.8rem',
31+
},
32+
},
33+
},
34+
},
35+
};
36+
2437
if (!sessionId){
2538
return(<p>No session Id provided.</p>)
2639
}
@@ -66,7 +79,7 @@ function VariantTable() {
6679

6780
setState(state)
6881
// @ts-ignore
69-
setTheme(createJBrowseTheme(readConfObject(state.config.configuration, 'theme')))
82+
setTheme(createTheme(deepmerge(createJBrowseTheme(readConfObject(state.config.configuration, 'theme')), themeAdditions)))
7083
}
7184

7285
// NOTE: pass trackId for activeTracks, to ensure view.tracks contains it

jbrowse/src/client/JBrowse/VariantSearch/components/FilterForm.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,17 +98,30 @@ const FilterForm = (props: FilterFormProps ) => {
9898
return i !== index;
9999
})
100100
);
101-
}};
101+
}
102+
};
102103

103104
const handleFilterChange = (index, key, value) => {
104105
const newFilters = filters.map((filter, i) => {
105106
if (i === index) {
106-
return Object.assign(new Filter(), { ...filter, [key]: value });
107+
const updatedFilter = Object.assign(new Filter(), { ...filter, [key]: value });
108+
109+
if (key === "operator") {
110+
if (value === "is empty" || value === "is not empty") {
111+
updatedFilter.value = '';
112+
}
113+
114+
if (value === "in set" || filter.operator === "in set") {
115+
updatedFilter.value = '';
116+
}
117+
}
118+
119+
return updatedFilter;
107120
}
108121
return filter;
109122
});
110123

111-
localSetFilters(newFilters)
124+
localSetFilters(newFilters);
112125
};
113126

114127
const handleSubmit = (event) => {
@@ -203,7 +216,7 @@ const FilterForm = (props: FilterFormProps ) => {
203216
handleFilterChange(index, "field", event.target.value)
204217
}
205218
>
206-
<MenuItem value="">
219+
<MenuItem value="" style={{ display: 'none' }}>
207220
<em>None</em>
208221
</MenuItem>
209222
{fieldTypeInfo.map((field) => (
@@ -223,7 +236,7 @@ const FilterForm = (props: FilterFormProps ) => {
223236
handleFilterChange(index, "operator", event.target.value)
224237
}
225238
>
226-
<MenuItem value="None">
239+
<MenuItem value="None" style={{ display: 'none' }}>
227240
<em>None</em>
228241
</MenuItem>
229242

@@ -262,6 +275,7 @@ const FilterForm = (props: FilterFormProps ) => {
262275
<Select
263276
labelId="value-select-label"
264277
value={filter.value}
278+
disabled={filter.operator === "is empty" || filter.operator === "is not empty"}
265279
onChange={(event) =>
266280
handleFilterChange(index, "value", event.target.value)
267281
}
@@ -278,6 +292,7 @@ const FilterForm = (props: FilterFormProps ) => {
278292
label="Value"
279293
sx={ highlightedInputs[index]?.value ? highlightedSx : null }
280294
value={filter.value}
295+
disabled={filter.operator === "is empty" || filter.operator === "is not empty"}
281296
onChange={(event) =>
282297
handleFilterChange(index, 'value', event.target.value)
283298
}

jbrowse/src/client/JBrowse/VariantSearch/components/VariantTableWidget.tsx

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ import {
1010
GridToolbarDensitySelector,
1111
GridToolbarExport
1212
} from '@mui/x-data-grid';
13-
import ScopedCssBaseline from '@mui/material/ScopedCssBaseline';
1413
import SearchIcon from '@mui/icons-material/Search';
15-
import React, { useEffect, useState } from 'react';
14+
import React, { useEffect, useState, useMemo } from 'react';
1615
import { getConf } from '@jbrowse/core/configuration';
1716
import { AppBar, Box, Button, Dialog, Paper, Popover, Toolbar, Tooltip, Typography } from '@mui/material';
1817
import ArrowPagination from './ArrowPagination';
@@ -69,11 +68,14 @@ const VariantTableWidget = observer(props => {
6968
session.hideWidget(widget)
7069
}
7170

72-
function handleQuery(passedFilters) {
71+
function handleQuery(passedFilters, pushToHistory) {
7372
const encodedSearchString = createEncodedFilterString(passedFilters, false);
7473
const currentUrl = new URL(window.location.href);
7574
currentUrl.searchParams.set("searchString", encodedSearchString);
76-
window.history.pushState(null, "", currentUrl.toString());
75+
76+
if (pushToHistory) {
77+
window.history.pushState(null, "", currentUrl.toString());
78+
}
7779

7880
setFilters(passedFilters);
7981
setDataLoaded(false)
@@ -235,6 +237,11 @@ const VariantTableWidget = observer(props => {
235237

236238
// API call to retrieve the requested features.
237239
useEffect(() => {
240+
const handlePopState = () => {
241+
window.location.reload();
242+
};
243+
window.addEventListener('popstate', handlePopState);
244+
238245
async function fetch() {
239246
await fetchFieldTypeInfo(sessionId, trackGUID,
240247
(fields: FieldModel[], groups: string[], promotedFilters: Map<string, Filter[]>) => {
@@ -256,14 +263,17 @@ const VariantTableWidget = observer(props => {
256263
setAllowedGroupNames(groups)
257264
setPromotedFilters(promotedFilters)
258265

259-
handleQuery(searchStringToInitialFilters(fields.map((x) => x.name)))
266+
handleQuery(searchStringToInitialFilters(fields.map((x) => x.name)), false)
260267
},
261268
(error) => {
262269
setError(error)
263270
})
264271
}
265272

266273
fetch()
274+
return () => {
275+
window.removeEventListener('popstate', handlePopState);
276+
};
267277

268278
}, [pluginManager, parsedLocString, session.visibleWidget])
269279

@@ -296,11 +306,6 @@ const VariantTableWidget = observer(props => {
296306

297307
const showDetailsWidget = (rowIdx: number, params: any) => {
298308
(async () => {
299-
/*let a = adapter;
300-
301-
if (!a) {
302-
a = await getAdapterInstance();
303-
}*/
304309
let a = await getAdapterInstance();
305310

306311
const row = features[rowIdx] as any
@@ -326,9 +331,6 @@ const VariantTableWidget = observer(props => {
326331
}
327332

328333
const feature = extendedFeatures[0]
329-
console.log(feature)
330-
console.log(row)
331-
332334
const trackId = getConf(track, 'trackId')
333335
const detailsConfig = getConf(track, ['displays', '0', 'detailsConfig'])
334336
const widgetId = 'Variant-' + trackId;
@@ -394,11 +396,12 @@ const VariantTableWidget = observer(props => {
394396
const renderHeaderCell = (params) => {
395397
return (
396398
<Tooltip title={params.colDef.description}>
397-
<div>{params.colDef.headerName}</div>
399+
<div style={{fontSize: 16}}>{params.colDef.headerName}</div>
398400
</Tooltip>
399401
);
400402
};
401403

404+
402405
const filterModal = (
403406
<FilterFormModal
404407
open={filterModalOpen}
@@ -408,7 +411,7 @@ const VariantTableWidget = observer(props => {
408411
fieldTypeInfo: fieldTypeInfo,
409412
allowedGroupNames: allowedGroupNames,
410413
promotedFilters: promotedFilters,
411-
handleQuery: (filters) => handleQuery(filters)
414+
handleQuery: (filters) => handleQuery(filters, true)
412415
}}
413416
/>
414417
);
@@ -434,22 +437,27 @@ const VariantTableWidget = observer(props => {
434437
<Typography variant="h6">{widgetType.heading}</Typography>
435438
</Toolbar>
436439
</AppBar>
437-
<ScopedCssBaseline>
438-
<ReactComponent model={visibleWidget}/>
439-
</ScopedCssBaseline>
440+
441+
<Box sx={{ margin: '12px' }}>
442+
<ReactComponent model={visibleWidget} style={{ margin: '12px' }}/>
443+
</Box>
440444
</Paper>
441445
</Dialog>
442446
)
443447
})
444448
}
445449

446-
447450
<div style={{ marginBottom: "10px", display: "flex", alignItems: "center" }}>
448-
449451
<div style={{ flex: 1 }}>
450452
{filters.map((filter, index) => {
451453
if ((filter as any).field == "" || (filter as any).operator == "" || (filter as any).value == "" ) {
452-
return null;
454+
return (<Button
455+
key={index}
456+
onClick={() => setFilterModalOpen(true)}
457+
style={{ border: "1px solid gray", margin: "5px" }}
458+
>
459+
No filters
460+
</Button>)
453461
}
454462
return (
455463
<Button

jbrowse/src/client/JBrowse/VariantTable/VariantTable.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { createTheme } from '@mui/material/styles';
55
import { readConfObject } from '@jbrowse/core/configuration';
66
import { createJBrowseTheme } from '@jbrowse/core/ui';
77
import { ThemeProvider } from '@mui/material';
8+
import { parseLocString } from '@jbrowse/core/util';
89
import LogSession from '../Browser/plugins/LogSession/index';
910
import ExtendedVariantPlugin from '../Browser/plugins/ExtendedVariantPlugin/index';
1011
import VariantTableWidget from './components/VariantTableWidget';
@@ -35,6 +36,7 @@ function VariantTable() {
3536
const [state, setState] = useState(null);
3637
const [theme, setTheme] = useState(null);
3738
const [view, setView] = useState(null);
39+
const [parsedLocString, setParsedLocString] = useState(null)
3840
const [pluginManager, setPluginManager] = useState(null);
3941
const [assembly, setAssembly] = useState<Assembly>(null);
4042
const [assemblyName, setAssemblyName] = useState<string>(null)
@@ -54,6 +56,15 @@ function VariantTable() {
5456
setPluginManager(pluginManager)
5557
setState(state)
5658

59+
const isValidRefNameForAssembly = function(refName: string, assemblyName?: string) {
60+
return assemblyManager.isValidRefName(refName, assemblyNames[0])
61+
}
62+
63+
if (locString) {
64+
const parsedLocString = parseLocString(locString, isValidRefNameForAssembly)
65+
setParsedLocString(parsedLocString)
66+
}
67+
5768
// @ts-ignore
5869
setTheme(createJBrowseTheme(readConfObject(state.config.configuration, 'theme')))
5970
}
@@ -80,7 +91,7 @@ function VariantTable() {
8091
<ErrorBoundary>
8192
<JBrowseFilterPanel session={state.session}/>
8293
<VariantTableWidget assembly={assembly} assemblyName={assemblyName} trackId={trackId} locString={locString}
83-
sessionId={sessionId} session={session} pluginManager={pluginManager}/>
94+
sessionId={sessionId} session={session} pluginManager={pluginManager} />
8495
</ErrorBoundary>
8596
</div>
8697
</ThemeProvider>

jbrowse/src/client/JBrowse/VariantTable/components/VariantTableWidget.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ const VariantTableWidget = observer(props => {
7878
navigateToBrowser(sessionId, locString, trackId, track)
7979
break;
8080
case "luceneRedirect":
81-
navigateToSearch(sessionId, locString, trackId, track)
81+
navigateToSearch(sessionId, locString, trackId, isValidRefNameForAssembly, track)
8282
break;
8383
}
8484
}

jbrowse/src/client/JBrowse/utils.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
GridFilterItem,
1111
GridFilterOperator
1212
} from '@mui/x-data-grid';
13-
import { ParsedLocString } from '@jbrowse/core/util';
13+
import { ParsedLocString, parseLocString } from '@jbrowse/core/util';
1414

1515
export function arrayMax(array) {
1616
return Array.isArray(array) ? Math.max(...array) : array
@@ -223,10 +223,21 @@ export function navigateToTable(sessionId, locString, trackId, track?: any) {
223223
window.location.href = ActionURL.buildURL("jbrowse", "variantTable.view", null, {session: sessionId, location: locString, trackId: trackId, activeTracks: trackId, sampleFilters: sampleFilterURL, infoFilters: infoFilterURL})
224224
}
225225

226-
export function navigateToSearch(sessionId, locString, trackId, track?: any) {
226+
export function navigateToSearch(sessionId, locString, trackId, isValidRefNameForAssembly, track?: any) {
227227
const sampleFilterURL = serializeSampleFilters(track)
228228
const infoFilterURL = serializeInfoFilters(track)
229-
window.location.href = ActionURL.buildURL("jbrowse", "variantSearch.view", null, {session: sessionId, location: locString, trackId: trackId, activeTracks: trackId, sampleFilters: sampleFilterURL, infoFilters: infoFilterURL})
229+
230+
let searchString = null
231+
if (locString && isValidRefNameForAssembly) {
232+
const parsedLocString = parseLocString(locString, isValidRefNameForAssembly)
233+
const contig = parsedLocString.refName;
234+
const start = parsedLocString.start;
235+
const end = parsedLocString.end;
236+
237+
searchString = serializeLocationToLuceneQuery(contig, start, end)
238+
}
239+
240+
window.location.href = ActionURL.buildURL("jbrowse", "variantSearch.view", null, {session: sessionId, location: locString, trackId: trackId, activeTracks: trackId, sampleFilters: sampleFilterURL, infoFilters: infoFilterURL, searchString: searchString})
230241
}
231242

232243
export function navigateToBrowser(sessionId: string, locString: string, trackGUID?: string, track?: any) {
@@ -301,6 +312,16 @@ export function getGenotypeURL(trackId, contig, start, end) {
301312
return ActionURL.buildURL("jbrowse", "genotypeTable.view", null, {trackId: trackId, chr: contig, start: start, stop: end})
302313
}
303314

315+
export function serializeLocationToLuceneQuery(contig, start, end) {
316+
const filters = [
317+
{field: "contig", operator: "equals", value: contig.toString()},
318+
{field: "start", operator: ">=", value: start.toString()},
319+
{field: "end", operator: "<=", value: end.toString()}
320+
]
321+
322+
return createEncodedFilterString(filters, false)
323+
}
324+
304325
function generateLuceneString(field, operator, value) {
305326
let luceneQueryString = '';
306327

@@ -583,7 +604,10 @@ export class Filter implements FilterType {
583604
const searchStringsArray = decodedSearchString.split("&").filter((x) => x !== "all")
584605

585606
return searchStringsArray.map((item) => {
586-
const [field, operator, value] = item.split(",")
607+
const parts = item.split(",");
608+
const field = parts[0];
609+
const operator = parts[1];
610+
const value = parts.slice(2).join(",");
587611
return Object.assign(new Filter(), { field: field, operator: operator, value: value })
588612
})
589613
}

0 commit comments

Comments
 (0)