@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.
- package/dist/ChordVariantDisplay/index.js +0 -1
- package/dist/ChordVariantDisplay/models/configSchema.js +0 -1
- package/dist/ChordVariantDisplay/models/stateModelFactory.d.ts +11 -3
- package/dist/ChordVariantDisplay/models/stateModelFactory.js +0 -1
- package/dist/LinearVariantDisplay/configSchema.js +0 -1
- package/dist/LinearVariantDisplay/index.js +0 -1
- package/dist/LinearVariantDisplay/model.d.ts +52 -49
- package/dist/LinearVariantDisplay/model.js +0 -1
- package/dist/StructuralVariantChordRenderer/Chord.d.ts +2 -1
- package/dist/StructuralVariantChordRenderer/Chord.js +0 -1
- package/dist/StructuralVariantChordRenderer/ReactComponent.d.ts +2 -1
- package/dist/StructuralVariantChordRenderer/ReactComponent.js +0 -1
- package/dist/StructuralVariantChordRenderer/configSchema.js +0 -1
- package/dist/StructuralVariantChordRenderer/index.js +0 -1
- package/dist/VariantFeatureWidget/AnnotGrid.d.ts +2 -1
- package/dist/VariantFeatureWidget/AnnotGrid.js +8 -14
- package/dist/VariantFeatureWidget/BreakendOptionDialog.d.ts +2 -1
- package/dist/VariantFeatureWidget/BreakendOptionDialog.js +0 -1
- package/dist/VariantFeatureWidget/BreakendPanel.d.ts +2 -1
- package/dist/VariantFeatureWidget/BreakendPanel.js +0 -1
- package/dist/VariantFeatureWidget/VariantAnnotationTable.d.ts +6 -0
- package/dist/VariantFeatureWidget/VariantAnnotationTable.js +16 -0
- package/dist/VariantFeatureWidget/VariantFeatureWidget.d.ts +8 -1
- package/dist/VariantFeatureWidget/VariantFeatureWidget.js +26 -15
- package/dist/VariantFeatureWidget/VariantSampleGrid.d.ts +9 -2
- package/dist/VariantFeatureWidget/VariantSampleGrid.js +0 -1
- package/dist/VariantFeatureWidget/index.js +0 -1
- package/dist/VariantTrack/configSchema.js +0 -1
- package/dist/VariantTrack/index.js +0 -1
- package/dist/VcfAdapter/VcfAdapter.js +0 -1
- package/dist/VcfAdapter/configSchema.js +0 -1
- package/dist/VcfAdapter/index.js +0 -1
- package/dist/VcfFeature/index.js +2 -2
- package/dist/VcfFeature/util.js +0 -1
- package/dist/VcfTabixAdapter/VcfTabixAdapter.js +0 -1
- package/dist/VcfTabixAdapter/configSchema.js +0 -1
- package/dist/VcfTabixAdapter/index.js +0 -1
- package/dist/extensionPoints.js +0 -1
- package/dist/index.js +0 -1
- package/esm/ChordVariantDisplay/index.js +0 -1
- package/esm/ChordVariantDisplay/models/configSchema.js +0 -1
- package/esm/ChordVariantDisplay/models/stateModelFactory.d.ts +11 -3
- package/esm/ChordVariantDisplay/models/stateModelFactory.js +0 -1
- package/esm/LinearVariantDisplay/configSchema.js +0 -1
- package/esm/LinearVariantDisplay/index.js +0 -1
- package/esm/LinearVariantDisplay/model.d.ts +52 -49
- package/esm/LinearVariantDisplay/model.js +0 -1
- package/esm/StructuralVariantChordRenderer/Chord.d.ts +2 -1
- package/esm/StructuralVariantChordRenderer/Chord.js +0 -1
- package/esm/StructuralVariantChordRenderer/ReactComponent.d.ts +2 -1
- package/esm/StructuralVariantChordRenderer/ReactComponent.js +0 -1
- package/esm/StructuralVariantChordRenderer/configSchema.js +0 -1
- package/esm/StructuralVariantChordRenderer/index.js +0 -1
- package/esm/VariantFeatureWidget/AnnotGrid.d.ts +2 -1
- package/esm/VariantFeatureWidget/AnnotGrid.js +8 -14
- package/esm/VariantFeatureWidget/BreakendOptionDialog.d.ts +2 -1
- package/esm/VariantFeatureWidget/BreakendOptionDialog.js +0 -1
- package/esm/VariantFeatureWidget/BreakendPanel.d.ts +2 -1
- package/esm/VariantFeatureWidget/BreakendPanel.js +0 -1
- package/esm/VariantFeatureWidget/VariantAnnotationTable.d.ts +6 -0
- package/esm/VariantFeatureWidget/VariantAnnotationTable.js +10 -0
- package/esm/VariantFeatureWidget/VariantFeatureWidget.d.ts +8 -1
- package/esm/VariantFeatureWidget/VariantFeatureWidget.js +26 -15
- package/esm/VariantFeatureWidget/VariantSampleGrid.d.ts +9 -2
- package/esm/VariantFeatureWidget/VariantSampleGrid.js +0 -1
- package/esm/VariantFeatureWidget/index.js +0 -1
- package/esm/VariantTrack/configSchema.js +0 -1
- package/esm/VariantTrack/index.js +0 -1
- package/esm/VcfAdapter/VcfAdapter.js +0 -1
- package/esm/VcfAdapter/configSchema.js +0 -1
- package/esm/VcfAdapter/index.js +0 -1
- package/esm/VcfFeature/index.js +2 -2
- package/esm/VcfFeature/util.js +0 -1
- package/esm/VcfTabixAdapter/VcfTabixAdapter.js +0 -1
- package/esm/VcfTabixAdapter/configSchema.js +0 -1
- package/esm/VcfTabixAdapter/index.js +0 -1
- package/esm/extensionPoints.js +0 -1
- package/esm/index.js +0 -1
- package/package.json +3 -4
- package/dist/ChordVariantDisplay/index.js.map +0 -1
- package/dist/ChordVariantDisplay/models/configSchema.js.map +0 -1
- package/dist/ChordVariantDisplay/models/stateModelFactory.js.map +0 -1
- package/dist/LinearVariantDisplay/configSchema.js.map +0 -1
- package/dist/LinearVariantDisplay/index.js.map +0 -1
- package/dist/LinearVariantDisplay/model.js.map +0 -1
- package/dist/StructuralVariantChordRenderer/Chord.js.map +0 -1
- package/dist/StructuralVariantChordRenderer/ReactComponent.js.map +0 -1
- package/dist/StructuralVariantChordRenderer/configSchema.js.map +0 -1
- package/dist/StructuralVariantChordRenderer/index.js.map +0 -1
- package/dist/VariantFeatureWidget/AnnotGrid.js.map +0 -1
- package/dist/VariantFeatureWidget/BreakendOptionDialog.js.map +0 -1
- package/dist/VariantFeatureWidget/BreakendPanel.js.map +0 -1
- package/dist/VariantFeatureWidget/VariantAnnPanel.d.ts +0 -4
- package/dist/VariantFeatureWidget/VariantAnnPanel.js +0 -25
- package/dist/VariantFeatureWidget/VariantAnnPanel.js.map +0 -1
- package/dist/VariantFeatureWidget/VariantCsqPanel.d.ts +0 -4
- package/dist/VariantFeatureWidget/VariantCsqPanel.js +0 -25
- package/dist/VariantFeatureWidget/VariantCsqPanel.js.map +0 -1
- package/dist/VariantFeatureWidget/VariantFeatureWidget.js.map +0 -1
- package/dist/VariantFeatureWidget/VariantSampleGrid.js.map +0 -1
- package/dist/VariantFeatureWidget/index.js.map +0 -1
- package/dist/VariantTrack/configSchema.js.map +0 -1
- package/dist/VariantTrack/index.js.map +0 -1
- package/dist/VcfAdapter/VcfAdapter.js.map +0 -1
- package/dist/VcfAdapter/configSchema.js.map +0 -1
- package/dist/VcfAdapter/index.js.map +0 -1
- package/dist/VcfFeature/index.js.map +0 -1
- package/dist/VcfFeature/util.js.map +0 -1
- package/dist/VcfTabixAdapter/VcfTabixAdapter.js.map +0 -1
- package/dist/VcfTabixAdapter/configSchema.js.map +0 -1
- package/dist/VcfTabixAdapter/index.js.map +0 -1
- package/dist/extensionPoints.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/esm/ChordVariantDisplay/index.js.map +0 -1
- package/esm/ChordVariantDisplay/models/configSchema.js.map +0 -1
- package/esm/ChordVariantDisplay/models/stateModelFactory.js.map +0 -1
- package/esm/LinearVariantDisplay/configSchema.js.map +0 -1
- package/esm/LinearVariantDisplay/index.js.map +0 -1
- package/esm/LinearVariantDisplay/model.js.map +0 -1
- package/esm/StructuralVariantChordRenderer/Chord.js.map +0 -1
- package/esm/StructuralVariantChordRenderer/ReactComponent.js.map +0 -1
- package/esm/StructuralVariantChordRenderer/configSchema.js.map +0 -1
- package/esm/StructuralVariantChordRenderer/index.js.map +0 -1
- package/esm/VariantFeatureWidget/AnnotGrid.js.map +0 -1
- package/esm/VariantFeatureWidget/BreakendOptionDialog.js.map +0 -1
- package/esm/VariantFeatureWidget/BreakendPanel.js.map +0 -1
- package/esm/VariantFeatureWidget/VariantAnnPanel.d.ts +0 -4
- package/esm/VariantFeatureWidget/VariantAnnPanel.js +0 -19
- package/esm/VariantFeatureWidget/VariantAnnPanel.js.map +0 -1
- package/esm/VariantFeatureWidget/VariantCsqPanel.d.ts +0 -4
- package/esm/VariantFeatureWidget/VariantCsqPanel.js +0 -19
- package/esm/VariantFeatureWidget/VariantCsqPanel.js.map +0 -1
- package/esm/VariantFeatureWidget/VariantFeatureWidget.js.map +0 -1
- package/esm/VariantFeatureWidget/VariantSampleGrid.js.map +0 -1
- package/esm/VariantFeatureWidget/index.js.map +0 -1
- package/esm/VariantTrack/configSchema.js.map +0 -1
- package/esm/VariantTrack/index.js.map +0 -1
- package/esm/VcfAdapter/VcfAdapter.js.map +0 -1
- package/esm/VcfAdapter/configSchema.js.map +0 -1
- package/esm/VcfAdapter/index.js.map +0 -1
- package/esm/VcfFeature/index.js.map +0 -1
- package/esm/VcfFeature/util.js.map +0 -1
- package/esm/VcfTabixAdapter/VcfTabixAdapter.js.map +0 -1
- package/esm/VcfTabixAdapter/configSchema.js.map +0 -1
- package/esm/VcfTabixAdapter/index.js.map +0 -1
- package/esm/extensionPoints.js.map +0 -1
- package/esm/index.js.map +0 -1
- package/src/ChordVariantDisplay/index.ts +0 -23
- package/src/ChordVariantDisplay/models/configSchema.ts +0 -33
- package/src/ChordVariantDisplay/models/stateModelFactory.ts +0 -63
- package/src/LinearVariantDisplay/configSchema.ts +0 -30
- package/src/LinearVariantDisplay/index.ts +0 -20
- package/src/LinearVariantDisplay/model.ts +0 -76
- package/src/StructuralVariantChordRenderer/Chord.tsx +0 -141
- package/src/StructuralVariantChordRenderer/ReactComponent.tsx +0 -78
- package/src/StructuralVariantChordRenderer/configSchema.ts +0 -42
- package/src/StructuralVariantChordRenderer/index.ts +0 -17
- package/src/VariantFeatureWidget/AnnotGrid.tsx +0 -52
- package/src/VariantFeatureWidget/BreakendOptionDialog.tsx +0 -117
- package/src/VariantFeatureWidget/BreakendPanel.tsx +0 -93
- package/src/VariantFeatureWidget/VariantAnnPanel.tsx +0 -31
- package/src/VariantFeatureWidget/VariantCsqPanel.tsx +0 -31
- package/src/VariantFeatureWidget/VariantFeatureWidget.test.tsx +0 -42
- package/src/VariantFeatureWidget/VariantFeatureWidget.tsx +0 -67
- package/src/VariantFeatureWidget/VariantSampleGrid.tsx +0 -152
- package/src/VariantFeatureWidget/__snapshots__/VariantFeatureWidget.test.tsx.snap +0 -244
- package/src/VariantFeatureWidget/index.ts +0 -32
- package/src/VariantTrack/configSchema.ts +0 -24
- package/src/VariantTrack/index.ts +0 -16
- package/src/VcfAdapter/VcfAdapter.test.ts +0 -28
- package/src/VcfAdapter/VcfAdapter.ts +0 -125
- package/src/VcfAdapter/__snapshots__/VcfAdapter.test.ts.snap +0 -325
- package/src/VcfAdapter/configSchema.ts +0 -22
- package/src/VcfAdapter/index.ts +0 -15
- package/src/VcfAdapter/test_data/volvox.filtered.vcf +0 -73
- package/src/VcfFeature/index.test.ts +0 -132
- package/src/VcfFeature/index.ts +0 -104
- package/src/VcfFeature/util.ts +0 -138
- package/src/VcfTabixAdapter/VcfTabixAdapter.test.ts +0 -69
- package/src/VcfTabixAdapter/VcfTabixAdapter.ts +0 -90
- package/src/VcfTabixAdapter/__snapshots__/VcfTabixAdapter.test.ts.snap +0 -325
- package/src/VcfTabixAdapter/configSchema.ts +0 -43
- package/src/VcfTabixAdapter/index.ts +0 -17
- package/src/VcfTabixAdapter/test_data/volvox.filtered.vcf.gz +0 -0
- package/src/VcfTabixAdapter/test_data/volvox.filtered.vcf.gz.csi +0 -0
- package/src/VcfTabixAdapter/test_data/volvox.filtered.vcf.gz.tbi +0 -0
- package/src/__snapshots__/index.test.ts.snap +0 -20
- package/src/extensionPoints.ts +0 -74
- package/src/index.test.ts +0 -32
- 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
|
-
<TRA>
|
|
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
|
-
}
|