@jbrowse/plugin-variants 2.5.0 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/dist/ChordVariantDisplay/index.js +0 -1
  2. package/dist/ChordVariantDisplay/models/configSchema.js +0 -1
  3. package/dist/ChordVariantDisplay/models/stateModelFactory.d.ts +11 -3
  4. package/dist/ChordVariantDisplay/models/stateModelFactory.js +0 -1
  5. package/dist/LinearVariantDisplay/configSchema.js +0 -1
  6. package/dist/LinearVariantDisplay/index.js +0 -1
  7. package/dist/LinearVariantDisplay/model.d.ts +52 -49
  8. package/dist/LinearVariantDisplay/model.js +0 -1
  9. package/dist/StructuralVariantChordRenderer/Chord.d.ts +2 -1
  10. package/dist/StructuralVariantChordRenderer/Chord.js +0 -1
  11. package/dist/StructuralVariantChordRenderer/ReactComponent.d.ts +2 -1
  12. package/dist/StructuralVariantChordRenderer/ReactComponent.js +0 -1
  13. package/dist/StructuralVariantChordRenderer/configSchema.js +0 -1
  14. package/dist/StructuralVariantChordRenderer/index.js +0 -1
  15. package/dist/VariantFeatureWidget/AnnotGrid.d.ts +2 -1
  16. package/dist/VariantFeatureWidget/AnnotGrid.js +8 -14
  17. package/dist/VariantFeatureWidget/BreakendOptionDialog.d.ts +2 -1
  18. package/dist/VariantFeatureWidget/BreakendOptionDialog.js +0 -1
  19. package/dist/VariantFeatureWidget/BreakendPanel.d.ts +2 -1
  20. package/dist/VariantFeatureWidget/BreakendPanel.js +0 -1
  21. package/dist/VariantFeatureWidget/VariantAnnotationTable.d.ts +6 -0
  22. package/dist/VariantFeatureWidget/VariantAnnotationTable.js +16 -0
  23. package/dist/VariantFeatureWidget/VariantFeatureWidget.d.ts +8 -1
  24. package/dist/VariantFeatureWidget/VariantFeatureWidget.js +26 -15
  25. package/dist/VariantFeatureWidget/VariantSampleGrid.d.ts +9 -2
  26. package/dist/VariantFeatureWidget/VariantSampleGrid.js +0 -1
  27. package/dist/VariantFeatureWidget/index.js +0 -1
  28. package/dist/VariantTrack/configSchema.js +0 -1
  29. package/dist/VariantTrack/index.js +0 -1
  30. package/dist/VcfAdapter/VcfAdapter.js +0 -1
  31. package/dist/VcfAdapter/configSchema.js +0 -1
  32. package/dist/VcfAdapter/index.js +0 -1
  33. package/dist/VcfFeature/index.js +2 -2
  34. package/dist/VcfFeature/util.js +0 -1
  35. package/dist/VcfTabixAdapter/VcfTabixAdapter.js +0 -1
  36. package/dist/VcfTabixAdapter/configSchema.js +0 -1
  37. package/dist/VcfTabixAdapter/index.js +0 -1
  38. package/dist/extensionPoints.js +0 -1
  39. package/dist/index.js +0 -1
  40. package/esm/ChordVariantDisplay/index.js +0 -1
  41. package/esm/ChordVariantDisplay/models/configSchema.js +0 -1
  42. package/esm/ChordVariantDisplay/models/stateModelFactory.d.ts +11 -3
  43. package/esm/ChordVariantDisplay/models/stateModelFactory.js +0 -1
  44. package/esm/LinearVariantDisplay/configSchema.js +0 -1
  45. package/esm/LinearVariantDisplay/index.js +0 -1
  46. package/esm/LinearVariantDisplay/model.d.ts +52 -49
  47. package/esm/LinearVariantDisplay/model.js +0 -1
  48. package/esm/StructuralVariantChordRenderer/Chord.d.ts +2 -1
  49. package/esm/StructuralVariantChordRenderer/Chord.js +0 -1
  50. package/esm/StructuralVariantChordRenderer/ReactComponent.d.ts +2 -1
  51. package/esm/StructuralVariantChordRenderer/ReactComponent.js +0 -1
  52. package/esm/StructuralVariantChordRenderer/configSchema.js +0 -1
  53. package/esm/StructuralVariantChordRenderer/index.js +0 -1
  54. package/esm/VariantFeatureWidget/AnnotGrid.d.ts +2 -1
  55. package/esm/VariantFeatureWidget/AnnotGrid.js +8 -14
  56. package/esm/VariantFeatureWidget/BreakendOptionDialog.d.ts +2 -1
  57. package/esm/VariantFeatureWidget/BreakendOptionDialog.js +0 -1
  58. package/esm/VariantFeatureWidget/BreakendPanel.d.ts +2 -1
  59. package/esm/VariantFeatureWidget/BreakendPanel.js +0 -1
  60. package/esm/VariantFeatureWidget/VariantAnnotationTable.d.ts +6 -0
  61. package/esm/VariantFeatureWidget/VariantAnnotationTable.js +10 -0
  62. package/esm/VariantFeatureWidget/VariantFeatureWidget.d.ts +8 -1
  63. package/esm/VariantFeatureWidget/VariantFeatureWidget.js +26 -15
  64. package/esm/VariantFeatureWidget/VariantSampleGrid.d.ts +9 -2
  65. package/esm/VariantFeatureWidget/VariantSampleGrid.js +0 -1
  66. package/esm/VariantFeatureWidget/index.js +0 -1
  67. package/esm/VariantTrack/configSchema.js +0 -1
  68. package/esm/VariantTrack/index.js +0 -1
  69. package/esm/VcfAdapter/VcfAdapter.js +0 -1
  70. package/esm/VcfAdapter/configSchema.js +0 -1
  71. package/esm/VcfAdapter/index.js +0 -1
  72. package/esm/VcfFeature/index.js +2 -2
  73. package/esm/VcfFeature/util.js +0 -1
  74. package/esm/VcfTabixAdapter/VcfTabixAdapter.js +0 -1
  75. package/esm/VcfTabixAdapter/configSchema.js +0 -1
  76. package/esm/VcfTabixAdapter/index.js +0 -1
  77. package/esm/extensionPoints.js +0 -1
  78. package/esm/index.js +0 -1
  79. package/package.json +3 -4
  80. package/dist/ChordVariantDisplay/index.js.map +0 -1
  81. package/dist/ChordVariantDisplay/models/configSchema.js.map +0 -1
  82. package/dist/ChordVariantDisplay/models/stateModelFactory.js.map +0 -1
  83. package/dist/LinearVariantDisplay/configSchema.js.map +0 -1
  84. package/dist/LinearVariantDisplay/index.js.map +0 -1
  85. package/dist/LinearVariantDisplay/model.js.map +0 -1
  86. package/dist/StructuralVariantChordRenderer/Chord.js.map +0 -1
  87. package/dist/StructuralVariantChordRenderer/ReactComponent.js.map +0 -1
  88. package/dist/StructuralVariantChordRenderer/configSchema.js.map +0 -1
  89. package/dist/StructuralVariantChordRenderer/index.js.map +0 -1
  90. package/dist/VariantFeatureWidget/AnnotGrid.js.map +0 -1
  91. package/dist/VariantFeatureWidget/BreakendOptionDialog.js.map +0 -1
  92. package/dist/VariantFeatureWidget/BreakendPanel.js.map +0 -1
  93. package/dist/VariantFeatureWidget/VariantAnnPanel.d.ts +0 -4
  94. package/dist/VariantFeatureWidget/VariantAnnPanel.js +0 -25
  95. package/dist/VariantFeatureWidget/VariantAnnPanel.js.map +0 -1
  96. package/dist/VariantFeatureWidget/VariantCsqPanel.d.ts +0 -4
  97. package/dist/VariantFeatureWidget/VariantCsqPanel.js +0 -25
  98. package/dist/VariantFeatureWidget/VariantCsqPanel.js.map +0 -1
  99. package/dist/VariantFeatureWidget/VariantFeatureWidget.js.map +0 -1
  100. package/dist/VariantFeatureWidget/VariantSampleGrid.js.map +0 -1
  101. package/dist/VariantFeatureWidget/index.js.map +0 -1
  102. package/dist/VariantTrack/configSchema.js.map +0 -1
  103. package/dist/VariantTrack/index.js.map +0 -1
  104. package/dist/VcfAdapter/VcfAdapter.js.map +0 -1
  105. package/dist/VcfAdapter/configSchema.js.map +0 -1
  106. package/dist/VcfAdapter/index.js.map +0 -1
  107. package/dist/VcfFeature/index.js.map +0 -1
  108. package/dist/VcfFeature/util.js.map +0 -1
  109. package/dist/VcfTabixAdapter/VcfTabixAdapter.js.map +0 -1
  110. package/dist/VcfTabixAdapter/configSchema.js.map +0 -1
  111. package/dist/VcfTabixAdapter/index.js.map +0 -1
  112. package/dist/extensionPoints.js.map +0 -1
  113. package/dist/index.js.map +0 -1
  114. package/esm/ChordVariantDisplay/index.js.map +0 -1
  115. package/esm/ChordVariantDisplay/models/configSchema.js.map +0 -1
  116. package/esm/ChordVariantDisplay/models/stateModelFactory.js.map +0 -1
  117. package/esm/LinearVariantDisplay/configSchema.js.map +0 -1
  118. package/esm/LinearVariantDisplay/index.js.map +0 -1
  119. package/esm/LinearVariantDisplay/model.js.map +0 -1
  120. package/esm/StructuralVariantChordRenderer/Chord.js.map +0 -1
  121. package/esm/StructuralVariantChordRenderer/ReactComponent.js.map +0 -1
  122. package/esm/StructuralVariantChordRenderer/configSchema.js.map +0 -1
  123. package/esm/StructuralVariantChordRenderer/index.js.map +0 -1
  124. package/esm/VariantFeatureWidget/AnnotGrid.js.map +0 -1
  125. package/esm/VariantFeatureWidget/BreakendOptionDialog.js.map +0 -1
  126. package/esm/VariantFeatureWidget/BreakendPanel.js.map +0 -1
  127. package/esm/VariantFeatureWidget/VariantAnnPanel.d.ts +0 -4
  128. package/esm/VariantFeatureWidget/VariantAnnPanel.js +0 -19
  129. package/esm/VariantFeatureWidget/VariantAnnPanel.js.map +0 -1
  130. package/esm/VariantFeatureWidget/VariantCsqPanel.d.ts +0 -4
  131. package/esm/VariantFeatureWidget/VariantCsqPanel.js +0 -19
  132. package/esm/VariantFeatureWidget/VariantCsqPanel.js.map +0 -1
  133. package/esm/VariantFeatureWidget/VariantFeatureWidget.js.map +0 -1
  134. package/esm/VariantFeatureWidget/VariantSampleGrid.js.map +0 -1
  135. package/esm/VariantFeatureWidget/index.js.map +0 -1
  136. package/esm/VariantTrack/configSchema.js.map +0 -1
  137. package/esm/VariantTrack/index.js.map +0 -1
  138. package/esm/VcfAdapter/VcfAdapter.js.map +0 -1
  139. package/esm/VcfAdapter/configSchema.js.map +0 -1
  140. package/esm/VcfAdapter/index.js.map +0 -1
  141. package/esm/VcfFeature/index.js.map +0 -1
  142. package/esm/VcfFeature/util.js.map +0 -1
  143. package/esm/VcfTabixAdapter/VcfTabixAdapter.js.map +0 -1
  144. package/esm/VcfTabixAdapter/configSchema.js.map +0 -1
  145. package/esm/VcfTabixAdapter/index.js.map +0 -1
  146. package/esm/extensionPoints.js.map +0 -1
  147. package/esm/index.js.map +0 -1
  148. package/src/ChordVariantDisplay/index.ts +0 -23
  149. package/src/ChordVariantDisplay/models/configSchema.ts +0 -33
  150. package/src/ChordVariantDisplay/models/stateModelFactory.ts +0 -63
  151. package/src/LinearVariantDisplay/configSchema.ts +0 -30
  152. package/src/LinearVariantDisplay/index.ts +0 -20
  153. package/src/LinearVariantDisplay/model.ts +0 -76
  154. package/src/StructuralVariantChordRenderer/Chord.tsx +0 -141
  155. package/src/StructuralVariantChordRenderer/ReactComponent.tsx +0 -78
  156. package/src/StructuralVariantChordRenderer/configSchema.ts +0 -42
  157. package/src/StructuralVariantChordRenderer/index.ts +0 -17
  158. package/src/VariantFeatureWidget/AnnotGrid.tsx +0 -52
  159. package/src/VariantFeatureWidget/BreakendOptionDialog.tsx +0 -117
  160. package/src/VariantFeatureWidget/BreakendPanel.tsx +0 -93
  161. package/src/VariantFeatureWidget/VariantAnnPanel.tsx +0 -31
  162. package/src/VariantFeatureWidget/VariantCsqPanel.tsx +0 -31
  163. package/src/VariantFeatureWidget/VariantFeatureWidget.test.tsx +0 -42
  164. package/src/VariantFeatureWidget/VariantFeatureWidget.tsx +0 -67
  165. package/src/VariantFeatureWidget/VariantSampleGrid.tsx +0 -152
  166. package/src/VariantFeatureWidget/__snapshots__/VariantFeatureWidget.test.tsx.snap +0 -244
  167. package/src/VariantFeatureWidget/index.ts +0 -32
  168. package/src/VariantTrack/configSchema.ts +0 -24
  169. package/src/VariantTrack/index.ts +0 -16
  170. package/src/VcfAdapter/VcfAdapter.test.ts +0 -28
  171. package/src/VcfAdapter/VcfAdapter.ts +0 -125
  172. package/src/VcfAdapter/__snapshots__/VcfAdapter.test.ts.snap +0 -325
  173. package/src/VcfAdapter/configSchema.ts +0 -22
  174. package/src/VcfAdapter/index.ts +0 -15
  175. package/src/VcfAdapter/test_data/volvox.filtered.vcf +0 -73
  176. package/src/VcfFeature/index.test.ts +0 -132
  177. package/src/VcfFeature/index.ts +0 -104
  178. package/src/VcfFeature/util.ts +0 -138
  179. package/src/VcfTabixAdapter/VcfTabixAdapter.test.ts +0 -69
  180. package/src/VcfTabixAdapter/VcfTabixAdapter.ts +0 -90
  181. package/src/VcfTabixAdapter/__snapshots__/VcfTabixAdapter.test.ts.snap +0 -325
  182. package/src/VcfTabixAdapter/configSchema.ts +0 -43
  183. package/src/VcfTabixAdapter/index.ts +0 -17
  184. package/src/VcfTabixAdapter/test_data/volvox.filtered.vcf.gz +0 -0
  185. package/src/VcfTabixAdapter/test_data/volvox.filtered.vcf.gz.csi +0 -0
  186. package/src/VcfTabixAdapter/test_data/volvox.filtered.vcf.gz.tbi +0 -0
  187. package/src/__snapshots__/index.test.ts.snap +0 -20
  188. package/src/extensionPoints.ts +0 -74
  189. package/src/index.test.ts +0 -32
  190. package/src/index.ts +0 -27
@@ -1,93 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import React, { useState } from 'react'
3
- import { Link, Typography } from '@mui/material'
4
- import SimpleFeature, {
5
- SimpleFeatureSerialized,
6
- } from '@jbrowse/core/util/simpleFeature'
7
- import { getEnv, getSession } from '@jbrowse/core/util'
8
- import { BaseCard } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
9
- import BreakendOptionDialog from './BreakendOptionDialog'
10
-
11
- export default function BreakendPanel(props: {
12
- locStrings: string[]
13
- model: any
14
- feature: SimpleFeatureSerialized
15
- }) {
16
- const { model, locStrings, feature } = props
17
- const session = getSession(model)
18
- const { pluginManager } = getEnv(session)
19
- const [breakpointDialog, setBreakpointDialog] = useState(false)
20
- let viewType
21
-
22
- try {
23
- viewType = pluginManager.getViewType('BreakpointSplitView')
24
- } catch (e) {
25
- // ignore
26
- }
27
-
28
- const simpleFeature = new SimpleFeature(feature)
29
- return (
30
- <BaseCard {...props} title="Breakends">
31
- <Typography>Link to linear view of breakend endpoints</Typography>
32
- <ul>
33
- {locStrings.map(locString => (
34
- <li key={`${JSON.stringify(locString)}`}>
35
- <Link
36
- href="#"
37
- onClick={event => {
38
- event.preventDefault()
39
- const { view } = model
40
- try {
41
- if (view) {
42
- view.navToLocString?.(locString)
43
- } else {
44
- throw new Error(
45
- 'No view associated with this feature detail panel anymore',
46
- )
47
- }
48
- } catch (e) {
49
- console.error(e)
50
- session.notify(`${e}`)
51
- }
52
- }}
53
- >
54
- {`LGV - ${locString}`}
55
- </Link>
56
- </li>
57
- ))}
58
- </ul>
59
- {viewType ? (
60
- <div>
61
- <Typography>
62
- Launch split views with breakend source and target
63
- </Typography>
64
- <ul>
65
- {locStrings.map(locString => (
66
- <li key={`${JSON.stringify(locString)}`}>
67
- <Link
68
- href="#"
69
- onClick={event => {
70
- event.preventDefault()
71
- setBreakpointDialog(true)
72
- }}
73
- >
74
- {`${feature.refName}:${feature.start} // ${locString} (split view)`}
75
- </Link>
76
- </li>
77
- ))}
78
- </ul>
79
- {breakpointDialog ? (
80
- <BreakendOptionDialog
81
- model={model}
82
- feature={simpleFeature}
83
- viewType={viewType}
84
- handleClose={() => {
85
- setBreakpointDialog(false)
86
- }}
87
- />
88
- ) : null}
89
- </div>
90
- ) : null}
91
- </BaseCard>
92
- )
93
- }
@@ -1,31 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import React from 'react'
3
- import { BaseCard } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
4
- import AnnotGrid from './AnnotGrid'
5
-
6
- export default function VariantAnnPanel({
7
- feature,
8
- descriptions,
9
- }: {
10
- feature: any
11
- descriptions: any
12
- }) {
13
- const annFields = (descriptions?.INFO?.ANN?.Description?.match(
14
- /.*Functional annotations:'(.*)'$/,
15
- )?.[1].split('|') || []) as string[]
16
- const ann = (feature.INFO.ANN || []) as string[]
17
-
18
- const rows =
19
- ann.map((elt, id) => ({
20
- id,
21
- ...Object.fromEntries(elt.split('|').map((e, i) => [annFields[i], e])),
22
- })) || []
23
- const columns = annFields.map(c => ({
24
- field: c,
25
- }))
26
- return ann.length ? (
27
- <BaseCard title="ANN table">
28
- <AnnotGrid rows={rows} columns={columns} />
29
- </BaseCard>
30
- ) : null
31
- }
@@ -1,31 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import React from 'react'
3
- import { BaseCard } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
4
- import AnnotGrid from './AnnotGrid'
5
-
6
- export default function VariantCsqPanel({
7
- feature,
8
- descriptions,
9
- }: {
10
- feature: any
11
- descriptions: any
12
- }) {
13
- const csqFields = (descriptions?.INFO?.CSQ?.Description?.match(
14
- /.*Format: (.*)/,
15
- )?.[1].split('|') || []) as string[]
16
-
17
- const csq = (feature.INFO.CSQ || []) as string[]
18
- const rows =
19
- csq.map((elt, id) => ({
20
- id,
21
- ...Object.fromEntries(elt.split('|').map((e, i) => [csqFields[i], e])),
22
- })) || []
23
- const columns = csqFields.map(c => ({
24
- field: c,
25
- }))
26
- return csq.length ? (
27
- <BaseCard title="CSQ table">
28
- <AnnotGrid rows={rows} columns={columns} />
29
- </BaseCard>
30
- ) : null
31
- }
@@ -1,42 +0,0 @@
1
- import React from 'react'
2
- import { render } from '@testing-library/react'
3
- import { types } from 'mobx-state-tree'
4
- import { ConfigurationSchema } from '@jbrowse/core/configuration'
5
- import PluginManager from '@jbrowse/core/PluginManager'
6
-
7
- // locals
8
- import { stateModelFactory } from '.'
9
- import VariantFeatureDetails from './VariantFeatureWidget'
10
-
11
- test('renders with just the required model elements', () => {
12
- const pluginManager = new PluginManager([])
13
- const Session = types.model({
14
- rpcManager: types.optional(types.frozen(), {}),
15
- configuration: ConfigurationSchema('test', {}),
16
- widget: stateModelFactory(pluginManager),
17
- })
18
- const model = Session.create(
19
- {
20
- widget: {
21
- // @ts-expect-error
22
- type: 'VariantFeatureWidget',
23
- },
24
- },
25
- { pluginManager },
26
- )
27
- model.widget.setFeatureData({
28
- refName: 'ctgA',
29
- start: 176,
30
- end: 177,
31
- name: 'rs123',
32
- REF: 'A',
33
- ALT: ['<TRA>'],
34
- QUAL: 10.4,
35
- INFO: {
36
- MQ: 5,
37
- },
38
- })
39
-
40
- const { container } = render(<VariantFeatureDetails model={model.widget} />)
41
- expect(container.firstChild).toMatchSnapshot()
42
- })
@@ -1,67 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import React from 'react'
3
- import { observer } from 'mobx-react'
4
- import { Divider, Paper } from '@mui/material'
5
- import { FeatureDetails } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
6
- import { parseBreakend } from '@gmod/vcf'
7
-
8
- // locals
9
- import VariantSampleGrid from './VariantSampleGrid'
10
- import VariantCsqPanel from './VariantCsqPanel'
11
- import VariantAnnPanel from './VariantAnnPanel'
12
- import BreakendPanel from './BreakendPanel'
13
-
14
- function VariantFeatureDetails(props: any) {
15
- const { model } = props
16
- const { featureData, descriptions } = model
17
- const feat = JSON.parse(JSON.stringify(featureData))
18
- const { samples, ...rest } = feat
19
- const basicDescriptions = {
20
- CHROM: 'chromosome: An identifier from the reference genome',
21
- POS: 'position: The reference position, with the 1st base having position 1',
22
- ID: 'identifier: Semi-colon separated list of unique identifiers where available',
23
- REF: 'reference base(s): Each base must be one of A,C,G,T,N (case insensitive).',
24
- ALT: 'alternate base(s): Comma-separated list of alternate non-reference alleles',
25
- QUAL: 'quality: Phred-scaled quality score for the assertion made in ALT',
26
- FILTER:
27
- 'filter status: PASS if this position has passed all filters, otherwise a semicolon-separated list of codes for filters that fail',
28
- }
29
-
30
- return (
31
- <Paper data-testid="variant-side-drawer">
32
- <FeatureDetails
33
- feature={rest}
34
- descriptions={{ ...basicDescriptions, ...descriptions }}
35
- {...props}
36
- />
37
- <Divider />
38
- <VariantCsqPanel feature={rest} descriptions={descriptions} />
39
- <Divider />
40
- <VariantAnnPanel feature={rest} descriptions={descriptions} />
41
- <Divider />
42
- {feat.type === 'breakend' ? (
43
- <BreakendPanel
44
- feature={feat}
45
- locStrings={feat.ALT.map(
46
- (alt: string) => parseBreakend(alt)?.MatePosition || '',
47
- )}
48
- model={model}
49
- />
50
- ) : null}
51
- {feat.type === 'translocation' ? (
52
- <BreakendPanel
53
- feature={feat}
54
- model={model}
55
- locStrings={[`${feat.INFO.CHR2[0]}:${feat.INFO.END}`]}
56
- />
57
- ) : null}
58
- <VariantSampleGrid
59
- feature={feat}
60
- {...props}
61
- descriptions={descriptions}
62
- />
63
- </Paper>
64
- )
65
- }
66
-
67
- export default observer(VariantFeatureDetails)
@@ -1,152 +0,0 @@
1
- import React, { useState } from 'react'
2
-
3
- import {
4
- FormControlLabel,
5
- Checkbox,
6
- TextField,
7
- Typography,
8
- } from '@mui/material'
9
-
10
- import { DataGrid, GridToolbar } from '@mui/x-data-grid'
11
- import { BaseCard } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
12
- import { measureGridWidth, SimpleFeatureSerialized } from '@jbrowse/core/util'
13
- import ResizeBar, { useResizeBar } from '@jbrowse/core/ui/ResizeBar'
14
-
15
- interface Entry {
16
- sample: string
17
- id: string
18
- [key: string]: string
19
- }
20
-
21
- type InfoFields = Record<string, unknown>
22
- type Filters = Record<string, string>
23
-
24
- function SampleFilters({
25
- columns,
26
- filter,
27
- setFilter,
28
- }: {
29
- columns: { field: string }[]
30
- filter: Filters
31
- setFilter: (arg: Filters) => void
32
- }) {
33
- return (
34
- <>
35
- <Typography>
36
- These filters can use a plain text search or regex style query, e.g. in
37
- the genotype field, entering 1 will query for all genotypes that include
38
- the first alternate allele e.g. 0|1 or 1|1, entering [1-9]\d* will find
39
- any non-zero allele e.g. 0|2 or 2/33
40
- </Typography>
41
- {columns.map(({ field }) => (
42
- <TextField
43
- key={`filter-${field}`}
44
- placeholder={`Filter ${field}`}
45
- value={filter[field] || ''}
46
- onChange={event =>
47
- setFilter({ ...filter, [field]: event.target.value })
48
- }
49
- />
50
- ))}
51
- </>
52
- )
53
- }
54
-
55
- export default function VariantSamples(props: {
56
- feature: SimpleFeatureSerialized
57
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
- descriptions: any
59
- }) {
60
- const { feature, descriptions = {} } = props
61
- const { ref, scrollLeft } = useResizeBar()
62
- const [filter, setFilter] = useState<Filters>({})
63
- const samples = (feature.samples || {}) as Record<string, InfoFields>
64
- const preFilteredRows = Object.entries(samples)
65
-
66
- let error
67
- let rows = [] as Entry[]
68
- const filters = Object.keys(filter)
69
-
70
- // catch some error thrown from regex
71
- // note: maps all values into a string, if this is not done rows are not
72
- // sortable by the data-grid
73
- try {
74
- rows = preFilteredRows
75
- .map(row => {
76
- return {
77
- ...Object.fromEntries(
78
- Object.entries(row[1]).map(e => [e[0], `${e[1]}`]),
79
- ),
80
- sample: row[0],
81
- id: row[0],
82
- } as Entry
83
- })
84
- .filter(row =>
85
- filters.length
86
- ? filters.every(key => {
87
- const currFilter = filter[key]
88
- return currFilter
89
- ? row[key].match(new RegExp(currFilter, 'i'))
90
- : true
91
- })
92
- : true,
93
- )
94
- } catch (e) {
95
- error = e
96
- }
97
-
98
- const keys = ['sample', ...Object.keys(preFilteredRows[0]?.[1] || {})]
99
- const [checked, setChecked] = useState(false)
100
- const [widths, setWidths] = useState(
101
- keys.map(e => measureGridWidth(rows.map(r => r[e]))),
102
- )
103
- const columns = keys.map((field, index) => ({
104
- field,
105
- description: descriptions.FORMAT?.[field]?.Description,
106
- width: widths[index],
107
- }))
108
-
109
- // disableRowSelectionOnClick helps avoid
110
- // https://github.com/mui-org/material-ui-x/issues/1197
111
- return !preFilteredRows.length ? null : (
112
- <BaseCard {...props} title="Samples">
113
- {error ? <Typography color="error">{`${error}`}</Typography> : null}
114
- <FormControlLabel
115
- control={
116
- <Checkbox
117
- checked={checked}
118
- onChange={event => setChecked(event.target.checked)}
119
- />
120
- }
121
- label={<Typography variant="body2">Show options</Typography>}
122
- />
123
- {checked ? (
124
- <SampleFilters
125
- setFilter={setFilter}
126
- columns={columns}
127
- filter={filter}
128
- />
129
- ) : null}
130
- <div ref={ref}>
131
- <ResizeBar
132
- widths={widths}
133
- setWidths={setWidths}
134
- scrollLeft={scrollLeft}
135
- />
136
- <DataGrid
137
- rows={rows}
138
- hideFooter={rows.length < 100}
139
- columns={columns}
140
- disableRowSelectionOnClick
141
- rowHeight={25}
142
- columnHeaderHeight={35}
143
- disableColumnMenu
144
- slots={{ toolbar: checked ? GridToolbar : null }}
145
- slotProps={{
146
- toolbar: { printOptions: { disableToolbarButton: true } },
147
- }}
148
- />
149
- </div>
150
- </BaseCard>
151
- )
152
- }
@@ -1,244 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`renders with just the required model elements 1`] = `
4
- <div
5
- class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-1ps6pg7-MuiPaper-root"
6
- data-testid="variant-side-drawer"
7
- >
8
- <div
9
- class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 MuiAccordion-root MuiAccordion-rounded Mui-expanded MuiAccordion-gutters css-1elwnq4-MuiPaper-root-MuiAccordion-root"
10
- >
11
- <div
12
- aria-expanded="true"
13
- class="MuiButtonBase-root MuiAccordionSummary-root Mui-expanded MuiAccordionSummary-gutters css-sh22l5-MuiButtonBase-root-MuiAccordionSummary-root"
14
- role="button"
15
- tabindex="0"
16
- >
17
- <div
18
- class="MuiAccordionSummary-content Mui-expanded MuiAccordionSummary-contentGutters css-o4b71y-MuiAccordionSummary-content"
19
- >
20
- <span
21
- class="MuiTypography-root MuiTypography-button css-1f0on15-MuiTypography-root"
22
- >
23
-
24
- rs123
25
- </span>
26
- </div>
27
- <div
28
- class="MuiAccordionSummary-expandIconWrapper Mui-expanded css-yw020d-MuiAccordionSummary-expandIconWrapper"
29
- >
30
- <svg
31
- aria-hidden="true"
32
- class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-ymsoo8-MuiSvgIcon-root-expandIcon"
33
- data-testid="ExpandMoreIcon"
34
- focusable="false"
35
- viewBox="0 0 24 24"
36
- >
37
- <path
38
- d="M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z"
39
- />
40
- </svg>
41
- </div>
42
- </div>
43
- <div
44
- class="MuiCollapse-root MuiCollapse-vertical MuiCollapse-entered css-pwcg7p-MuiCollapse-root"
45
- style="min-height: 0px;"
46
- >
47
- <div
48
- class="MuiCollapse-wrapper MuiCollapse-vertical css-smkl36-MuiCollapse-wrapper"
49
- >
50
- <div
51
- class="MuiCollapse-wrapperInner MuiCollapse-vertical css-9l5vo-MuiCollapse-wrapperInner"
52
- >
53
- <div
54
- class="MuiAccordion-region"
55
- role="region"
56
- >
57
- <div
58
- class="MuiAccordionDetails-root css-rqrb7m-MuiAccordionDetails-root-expansionPanelDetails"
59
- >
60
- <p
61
- class="MuiTypography-root MuiTypography-body1 css-ahj2mt-MuiTypography-root"
62
- >
63
- Core details
64
- </p>
65
- <div
66
- class="css-1m8nxnb-field"
67
- >
68
- <div
69
- class="css-1q83rf3-fieldName"
70
- >
71
- Position
72
- </div>
73
- <div
74
- class="css-1omt041-fieldValue"
75
- >
76
- ctgA:177
77
- </div>
78
- </div>
79
- <div
80
- class="css-1m8nxnb-field"
81
- >
82
- <div
83
- class="css-1q83rf3-fieldName"
84
- >
85
- Name
86
- </div>
87
- <div
88
- class="css-1omt041-fieldValue"
89
- >
90
- <span>
91
- rs123
92
- </span>
93
- </div>
94
- </div>
95
- <div
96
- class="css-1m8nxnb-field"
97
- >
98
- <div
99
- class="css-1q83rf3-fieldName"
100
- >
101
- Length
102
- </div>
103
- <div
104
- class="css-1omt041-fieldValue"
105
- >
106
- <span>
107
- 1
108
- </span>
109
- </div>
110
- </div>
111
- <hr
112
- class="MuiDivider-root MuiDivider-fullWidth css-9mgopn-MuiDivider-root"
113
- />
114
- <p
115
- class="MuiTypography-root MuiTypography-body1 css-ahj2mt-MuiTypography-root"
116
- >
117
- Attributes
118
- </p>
119
- <div
120
- class="css-1m8nxnb-field"
121
- >
122
- <div
123
- aria-label="reference base(s): Each base must be one of A,C,G,T,N (case insensitive)."
124
- class="css-18vnxxj-fieldDescription-fieldName"
125
- data-mui-internal-clone-element="true"
126
- >
127
- REF
128
- </div>
129
- <div
130
- class="css-1omt041-fieldValue"
131
- >
132
- <span>
133
- A
134
- </span>
135
- </div>
136
- </div>
137
- <div
138
- class="css-1m8nxnb-field"
139
- >
140
- <div
141
- aria-label="alternate base(s): Comma-separated list of alternate non-reference alleles"
142
- class="css-18vnxxj-fieldDescription-fieldName"
143
- data-mui-internal-clone-element="true"
144
- >
145
- ALT
146
- </div>
147
- <div
148
- class="css-1omt041-fieldValue"
149
- >
150
- <span>
151
- &lt;TRA&gt;
152
- </span>
153
- </div>
154
- </div>
155
- <div
156
- class="css-1m8nxnb-field"
157
- >
158
- <div
159
- aria-label="quality: Phred-scaled quality score for the assertion made in ALT"
160
- class="css-18vnxxj-fieldDescription-fieldName"
161
- data-mui-internal-clone-element="true"
162
- >
163
- QUAL
164
- </div>
165
- <div
166
- class="css-1omt041-fieldValue"
167
- >
168
- <span>
169
- 10.4
170
- </span>
171
- </div>
172
- </div>
173
- <div
174
- class="css-1m8nxnb-field"
175
- >
176
- <div
177
- class="css-1q83rf3-fieldName"
178
- style="width: 62px;"
179
- >
180
- INFO.MQ
181
- </div>
182
- <div
183
- class="css-1omt041-fieldValue"
184
- >
185
- <span>
186
- 5
187
- </span>
188
- </div>
189
- </div>
190
- <div
191
- class="css-1lttu3w-container"
192
- >
193
- <button
194
- class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium css-sghohy-MuiButtonBase-root-MuiButton-root"
195
- tabindex="0"
196
- type="button"
197
- >
198
- Show feature sequence
199
- <span
200
- class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
201
- />
202
- </button>
203
- <div
204
- class="MuiFormControl-root css-147opmv-MuiFormControl-root-formControl"
205
- >
206
- <button
207
- class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeMedium css-78trlr-MuiButtonBase-root-MuiIconButton-root"
208
- tabindex="0"
209
- type="button"
210
- >
211
- <svg
212
- aria-hidden="true"
213
- class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root"
214
- data-testid="HelpIcon"
215
- focusable="false"
216
- viewBox="0 0 24 24"
217
- >
218
- <path
219
- d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"
220
- />
221
- </svg>
222
- <span
223
- class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
224
- />
225
- </button>
226
- </div>
227
- </div>
228
- </div>
229
- </div>
230
- </div>
231
- </div>
232
- </div>
233
- </div>
234
- <hr
235
- class="MuiDivider-root MuiDivider-fullWidth css-9mgopn-MuiDivider-root"
236
- />
237
- <hr
238
- class="MuiDivider-root MuiDivider-fullWidth css-9mgopn-MuiDivider-root"
239
- />
240
- <hr
241
- class="MuiDivider-root MuiDivider-fullWidth css-9mgopn-MuiDivider-root"
242
- />
243
- </div>
244
- `;
@@ -1,32 +0,0 @@
1
- import { lazy } from 'react'
2
- import { ConfigurationSchema } from '@jbrowse/core/configuration'
3
- import WidgetType from '@jbrowse/core/pluggableElementTypes/WidgetType'
4
- import PluginManager from '@jbrowse/core/PluginManager'
5
- import { types } from 'mobx-state-tree'
6
- import { stateModelFactory as baseModelFactory } from '@jbrowse/core/BaseFeatureWidget'
7
-
8
- export const configSchema = ConfigurationSchema('VariantFeatureWidget', {})
9
-
10
- export function stateModelFactory(pluginManager: PluginManager) {
11
- const baseModel = baseModelFactory(pluginManager)
12
- return types.compose(
13
- baseModel,
14
- types.model('VariantFeatureWidget', {
15
- type: types.literal('VariantFeatureWidget'),
16
- descriptions: types.frozen(),
17
- }),
18
- )
19
- }
20
-
21
- export default (pluginManager: PluginManager) => {
22
- pluginManager.addWidgetType(
23
- () =>
24
- new WidgetType({
25
- name: 'VariantFeatureWidget',
26
- heading: 'Feature details',
27
- configSchema,
28
- stateModel: stateModelFactory(pluginManager),
29
- ReactComponent: lazy(() => import('./VariantFeatureWidget')),
30
- }),
31
- )
32
- }