@jbrowse/plugin-linear-genome-view 1.3.4 → 1.5.0
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/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +3 -2
- package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +20 -10
- package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +2 -2
- package/dist/LinearBareDisplay/model.d.ts +10 -9
- package/dist/LinearBasicDisplay/model.d.ts +13 -9
- package/dist/LinearGenomeView/components/Header.d.ts +2 -4
- package/dist/LinearGenomeView/components/RefNameAutocomplete.d.ts +1 -11
- package/dist/LinearGenomeView/components/ScaleBar.d.ts +46 -14
- package/dist/LinearGenomeView/components/util.d.ts +2 -0
- package/dist/LinearGenomeView/index.d.ts +13 -2
- package/dist/index.d.ts +47 -56
- package/dist/plugin-linear-genome-view.cjs.development.js +642 -423
- package/dist/plugin-linear-genome-view.cjs.development.js.map +1 -1
- package/dist/plugin-linear-genome-view.cjs.production.min.js +1 -1
- package/dist/plugin-linear-genome-view.cjs.production.min.js.map +1 -1
- package/dist/plugin-linear-genome-view.esm.js +652 -433
- package/dist/plugin-linear-genome-view.esm.js.map +1 -1
- package/package.json +4 -2
- package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +100 -21
- package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +10 -10
- package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +15 -13
- package/src/LinearBasicDisplay/model.ts +25 -3
- package/src/LinearGenomeView/components/ExportSvgDialog.tsx +17 -8
- package/src/LinearGenomeView/components/Header.tsx +101 -104
- package/src/LinearGenomeView/components/ImportForm.tsx +146 -113
- package/src/LinearGenomeView/components/LinearGenomeView.test.js +6 -6
- package/src/LinearGenomeView/components/OverviewScaleBar.tsx +4 -1
- package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +196 -169
- package/src/LinearGenomeView/components/SearchResultsDialog.tsx +1 -16
- package/src/LinearGenomeView/components/SequenceDialog.tsx +59 -58
- package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.js.snap +5 -177
- package/src/LinearGenomeView/components/util.ts +8 -0
- package/src/LinearGenomeView/index.tsx +39 -28
- package/src/index.ts +3 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-linear-genome-view",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "JBrowse 2 linear genome view",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@material-ui/icons": "^4.9.1",
|
|
39
|
+
"@popperjs/core": "^2.9.3",
|
|
39
40
|
"clone": "^2.1.2",
|
|
40
41
|
"clsx": "^1.0.4",
|
|
41
42
|
"copy-to-clipboard": "^3.3.1",
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
"is-object": "^1.0.1",
|
|
44
45
|
"json-stable-stringify": "^1.0.1",
|
|
45
46
|
"normalize-wheel": "^1.0.1",
|
|
47
|
+
"react-popper": "^2.0.0",
|
|
46
48
|
"react-sizeme": "^2.6.7"
|
|
47
49
|
},
|
|
48
50
|
"peerDependencies": {
|
|
@@ -59,5 +61,5 @@
|
|
|
59
61
|
"publishConfig": {
|
|
60
62
|
"access": "public"
|
|
61
63
|
},
|
|
62
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "542025578a39bd170c8a166f2568ee7edbd54072"
|
|
63
65
|
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
import React, { useState, useRef, useMemo } from 'react'
|
|
2
|
+
import { Portal, alpha, useTheme, makeStyles } from '@material-ui/core'
|
|
1
3
|
import { getConf } from '@jbrowse/core/configuration'
|
|
2
4
|
import { Menu } from '@jbrowse/core/ui'
|
|
3
|
-
import { useTheme, makeStyles } from '@material-ui/core/styles'
|
|
4
5
|
import { observer } from 'mobx-react'
|
|
5
|
-
import
|
|
6
|
-
|
|
6
|
+
import { usePopper } from 'react-popper'
|
|
7
|
+
|
|
8
|
+
// locals
|
|
7
9
|
import LinearBlocks from './LinearBlocks'
|
|
8
10
|
import { BaseLinearDisplayModel } from '../models/BaseLinearDisplayModel'
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
function round(value: number) {
|
|
13
|
+
return Math.round(value * 1e5) / 1e5
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const useStyles = makeStyles(theme => ({
|
|
11
17
|
display: {
|
|
12
18
|
position: 'relative',
|
|
13
19
|
whiteSpace: 'nowrap',
|
|
@@ -15,26 +21,89 @@ const useStyles = makeStyles({
|
|
|
15
21
|
width: '100%',
|
|
16
22
|
minHeight: '100%',
|
|
17
23
|
},
|
|
24
|
+
|
|
25
|
+
// these styles come from
|
|
26
|
+
// https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Tooltip/Tooltip.js
|
|
27
|
+
tooltip: {
|
|
28
|
+
pointerEvents: 'none',
|
|
29
|
+
backgroundColor: alpha(theme.palette.grey[700], 0.9),
|
|
30
|
+
borderRadius: theme.shape.borderRadius,
|
|
31
|
+
color: theme.palette.common.white,
|
|
32
|
+
fontFamily: theme.typography.fontFamily,
|
|
33
|
+
padding: '4px 8px',
|
|
34
|
+
fontSize: theme.typography.pxToRem(10),
|
|
35
|
+
lineHeight: `${round(14 / 10)}em`,
|
|
36
|
+
maxWidth: 300,
|
|
37
|
+
wordWrap: 'break-word',
|
|
38
|
+
fontWeight: theme.typography.fontWeightMedium,
|
|
39
|
+
},
|
|
40
|
+
}))
|
|
41
|
+
|
|
42
|
+
const TooltipContents = React.forwardRef<
|
|
43
|
+
HTMLDivElement,
|
|
44
|
+
{ message: React.ReactNode | string }
|
|
45
|
+
>(({ message }: { message: React.ReactNode | string }, ref) => {
|
|
46
|
+
return <div ref={ref}>{message}</div>
|
|
18
47
|
})
|
|
48
|
+
|
|
19
49
|
const Tooltip = observer(
|
|
20
|
-
(
|
|
21
|
-
|
|
50
|
+
({
|
|
51
|
+
model,
|
|
52
|
+
clientMouseCoord,
|
|
53
|
+
}: {
|
|
54
|
+
model: BaseLinearDisplayModel
|
|
55
|
+
clientMouseCoord: Coord
|
|
56
|
+
}) => {
|
|
57
|
+
const classes = useStyles()
|
|
22
58
|
const { featureUnderMouse } = model
|
|
23
|
-
const
|
|
59
|
+
const [width, setWidth] = useState(0)
|
|
60
|
+
|
|
61
|
+
const [popperElt, setPopperElt] = useState<HTMLDivElement | null>(null)
|
|
62
|
+
|
|
63
|
+
// must be memoized a la https://github.com/popperjs/react-popper/issues/391
|
|
64
|
+
const virtElement = useMemo(
|
|
65
|
+
() => ({
|
|
66
|
+
getBoundingClientRect: () => {
|
|
67
|
+
const x = clientMouseCoord[0] + width / 2 + 20
|
|
68
|
+
const y = clientMouseCoord[1]
|
|
69
|
+
return {
|
|
70
|
+
top: y,
|
|
71
|
+
left: x,
|
|
72
|
+
bottom: y,
|
|
73
|
+
right: x,
|
|
74
|
+
width: 0,
|
|
75
|
+
height: 0,
|
|
76
|
+
x,
|
|
77
|
+
y,
|
|
78
|
+
toJSON() {},
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
}),
|
|
82
|
+
[clientMouseCoord, width],
|
|
83
|
+
)
|
|
84
|
+
const { styles, attributes } = usePopper(virtElement, popperElt)
|
|
85
|
+
|
|
86
|
+
const contents = featureUnderMouse
|
|
24
87
|
? getConf(model, 'mouseover', { feature: featureUnderMouse })
|
|
25
88
|
: undefined
|
|
26
|
-
|
|
27
|
-
|
|
89
|
+
|
|
90
|
+
return featureUnderMouse && contents ? (
|
|
91
|
+
<Portal>
|
|
28
92
|
<div
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
93
|
+
ref={setPopperElt}
|
|
94
|
+
className={classes.tooltip}
|
|
95
|
+
// zIndex needed to go over widget drawer
|
|
96
|
+
style={{ ...styles.popper, zIndex: 100000 }}
|
|
97
|
+
{...attributes.popper}
|
|
34
98
|
>
|
|
35
|
-
|
|
99
|
+
<TooltipContents
|
|
100
|
+
ref={(elt: HTMLDivElement) =>
|
|
101
|
+
setWidth(elt?.getBoundingClientRect().width || 0)
|
|
102
|
+
}
|
|
103
|
+
message={contents}
|
|
104
|
+
/>
|
|
36
105
|
</div>
|
|
37
|
-
</
|
|
106
|
+
</Portal>
|
|
38
107
|
) : null
|
|
39
108
|
},
|
|
40
109
|
)
|
|
@@ -44,10 +113,11 @@ const BaseLinearDisplay = observer(
|
|
|
44
113
|
(props: { model: BaseLinearDisplayModel; children?: React.ReactNode }) => {
|
|
45
114
|
const classes = useStyles()
|
|
46
115
|
const theme = useTheme()
|
|
47
|
-
|
|
48
|
-
const [mouseCoord, setMouseCoord] = useState<Coord>([0, 0])
|
|
49
|
-
const [contextCoord, setContextCoord] = useState<Coord>()
|
|
50
116
|
const ref = useRef<HTMLDivElement>(null)
|
|
117
|
+
const [clientRect, setClientRect] = useState<ClientRect>()
|
|
118
|
+
const [offsetMouseCoord, setOffsetMouseCoord] = useState<Coord>([0, 0])
|
|
119
|
+
const [clientMouseCoord, setClientMouseCoord] = useState<Coord>([0, 0])
|
|
120
|
+
const [contextCoord, setContextCoord] = useState<Coord>()
|
|
51
121
|
const { model, children } = props
|
|
52
122
|
const {
|
|
53
123
|
TooltipComponent,
|
|
@@ -74,7 +144,12 @@ const BaseLinearDisplay = observer(
|
|
|
74
144
|
onMouseMove={event => {
|
|
75
145
|
if (ref.current) {
|
|
76
146
|
const rect = ref.current.getBoundingClientRect()
|
|
77
|
-
|
|
147
|
+
setOffsetMouseCoord([
|
|
148
|
+
event.clientX - rect.left,
|
|
149
|
+
event.clientY - rect.top,
|
|
150
|
+
])
|
|
151
|
+
setClientMouseCoord([event.clientX, event.clientY])
|
|
152
|
+
setClientRect(rect)
|
|
78
153
|
}
|
|
79
154
|
}}
|
|
80
155
|
role="presentation"
|
|
@@ -85,10 +160,14 @@ const BaseLinearDisplay = observer(
|
|
|
85
160
|
<LinearBlocks {...props} />
|
|
86
161
|
)}
|
|
87
162
|
{children}
|
|
163
|
+
|
|
88
164
|
<TooltipComponent
|
|
89
165
|
model={model}
|
|
90
166
|
height={height}
|
|
91
|
-
|
|
167
|
+
offsetMouseCoord={offsetMouseCoord}
|
|
168
|
+
clientMouseCoord={clientMouseCoord}
|
|
169
|
+
clientRect={clientRect}
|
|
170
|
+
mouseCoord={offsetMouseCoord}
|
|
92
171
|
/>
|
|
93
172
|
|
|
94
173
|
<Menu
|
|
@@ -88,7 +88,7 @@ export const BaseLinearDisplay = types
|
|
|
88
88
|
},
|
|
89
89
|
|
|
90
90
|
get TooltipComponent(): React.FC<any> {
|
|
91
|
-
return
|
|
91
|
+
return Tooltip as unknown as React.FC
|
|
92
92
|
},
|
|
93
93
|
|
|
94
94
|
/**
|
|
@@ -97,8 +97,7 @@ export const BaseLinearDisplay = types
|
|
|
97
97
|
*/
|
|
98
98
|
get selectedFeatureId() {
|
|
99
99
|
if (isAlive(self)) {
|
|
100
|
-
const
|
|
101
|
-
const { selection } = session
|
|
100
|
+
const { selection } = getSession(self)
|
|
102
101
|
// does it quack like a feature?
|
|
103
102
|
if (isFeature(selection)) {
|
|
104
103
|
return selection.id()
|
|
@@ -140,7 +139,12 @@ export const BaseLinearDisplay = types
|
|
|
140
139
|
return self.blockState.get(blockKey)?.layout?.getByCoord(x, y)
|
|
141
140
|
},
|
|
142
141
|
|
|
143
|
-
getFeatureByID(id: string):
|
|
142
|
+
getFeatureByID(blockKey: string, id: string): LayoutRecord | undefined {
|
|
143
|
+
return self.blockState.get(blockKey)?.layout?.getByID(id)
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
// if block key is not supplied, can look at all blocks
|
|
147
|
+
searchFeatureByID(id: string): LayoutRecord | undefined {
|
|
144
148
|
let ret
|
|
145
149
|
self.blockState.forEach(block => {
|
|
146
150
|
const val = block?.layout?.getByID(id)
|
|
@@ -383,12 +387,8 @@ export const BaseLinearDisplay = types
|
|
|
383
387
|
}
|
|
384
388
|
}
|
|
385
389
|
|
|
386
|
-
const {
|
|
387
|
-
|
|
388
|
-
renderArgs,
|
|
389
|
-
renderProps,
|
|
390
|
-
rendererType,
|
|
391
|
-
} = renderBlockData(blockState, self)
|
|
390
|
+
const { rpcManager, renderArgs, renderProps, rendererType } =
|
|
391
|
+
renderBlockData(blockState, self)
|
|
392
392
|
|
|
393
393
|
return rendererType.renderInClient(rpcManager, {
|
|
394
394
|
...renderArgs,
|
|
@@ -3,7 +3,10 @@ import { types, getParent, isAlive, cast, Instance } from 'mobx-state-tree'
|
|
|
3
3
|
import { readConfObject } from '@jbrowse/core/configuration'
|
|
4
4
|
import { Feature } from '@jbrowse/core/util/simpleFeature'
|
|
5
5
|
import { Region } from '@jbrowse/core/util/types/mst'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
AbstractDisplayModel,
|
|
8
|
+
isRetryException,
|
|
9
|
+
} from '@jbrowse/core/util/types'
|
|
7
10
|
import React from 'react'
|
|
8
11
|
|
|
9
12
|
import {
|
|
@@ -36,7 +39,7 @@ const blockState = types
|
|
|
36
39
|
features: undefined as Map<string, Feature> | undefined,
|
|
37
40
|
layout: undefined as any,
|
|
38
41
|
status: '',
|
|
39
|
-
error: undefined as
|
|
42
|
+
error: undefined as unknown,
|
|
40
43
|
message: undefined as string | undefined,
|
|
41
44
|
maxHeightReached: false,
|
|
42
45
|
ReactComponent: ServerSideRenderedBlockContent,
|
|
@@ -128,7 +131,7 @@ const blockState = types
|
|
|
128
131
|
self.renderProps = renderProps
|
|
129
132
|
renderInProgress = undefined
|
|
130
133
|
},
|
|
131
|
-
setError(error: Error) {
|
|
134
|
+
setError(error: Error | unknown) {
|
|
132
135
|
console.error(error)
|
|
133
136
|
if (renderInProgress && !renderInProgress.signal.aborted) {
|
|
134
137
|
renderInProgress.abort()
|
|
@@ -143,6 +146,9 @@ const blockState = types
|
|
|
143
146
|
self.error = error
|
|
144
147
|
self.renderProps = undefined
|
|
145
148
|
renderInProgress = undefined
|
|
149
|
+
if (isRetryException(error as Error)) {
|
|
150
|
+
this.reload()
|
|
151
|
+
}
|
|
146
152
|
},
|
|
147
153
|
reload() {
|
|
148
154
|
self.renderInProgress = undefined
|
|
@@ -286,16 +292,12 @@ async function renderBlockEffect(
|
|
|
286
292
|
return undefined
|
|
287
293
|
}
|
|
288
294
|
|
|
289
|
-
const {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
...renderArgs,
|
|
296
|
-
...renderProps,
|
|
297
|
-
signal,
|
|
298
|
-
})
|
|
295
|
+
const { reactElement, features, layout, maxHeightReached } =
|
|
296
|
+
await rendererType.renderInClient(rpcManager, {
|
|
297
|
+
...renderArgs,
|
|
298
|
+
...renderProps,
|
|
299
|
+
signal,
|
|
300
|
+
})
|
|
299
301
|
return {
|
|
300
302
|
reactElement,
|
|
301
303
|
features,
|
|
@@ -17,6 +17,7 @@ const stateModelFactory = (configSchema: AnyConfigurationSchemaType) =>
|
|
|
17
17
|
types.model({
|
|
18
18
|
type: types.literal('LinearBasicDisplay'),
|
|
19
19
|
trackShowLabels: types.maybe(types.boolean),
|
|
20
|
+
trackShowDescriptions: types.maybe(types.boolean),
|
|
20
21
|
trackDisplayMode: types.maybe(types.string),
|
|
21
22
|
trackMaxHeight: types.maybe(types.number),
|
|
22
23
|
configuration: ConfigurationReference(configSchema),
|
|
@@ -34,6 +35,13 @@ const stateModelFactory = (configSchema: AnyConfigurationSchemaType) =>
|
|
|
34
35
|
: showLabels
|
|
35
36
|
},
|
|
36
37
|
|
|
38
|
+
get showDescriptions() {
|
|
39
|
+
const showDescriptions = getConf(self, ['renderer', 'showLabels'])
|
|
40
|
+
return self.trackShowDescriptions !== undefined
|
|
41
|
+
? self.trackShowDescriptions
|
|
42
|
+
: showDescriptions
|
|
43
|
+
},
|
|
44
|
+
|
|
37
45
|
get maxHeight() {
|
|
38
46
|
const maxHeight = getConf(self, ['renderer', 'maxHeight'])
|
|
39
47
|
return self.trackMaxHeight !== undefined
|
|
@@ -54,6 +62,7 @@ const stateModelFactory = (configSchema: AnyConfigurationSchemaType) =>
|
|
|
54
62
|
{
|
|
55
63
|
...configBlob,
|
|
56
64
|
showLabels: this.showLabels,
|
|
65
|
+
showDescriptions: this.showDescriptions,
|
|
57
66
|
displayMode: this.displayMode,
|
|
58
67
|
maxHeight: this.maxHeight,
|
|
59
68
|
},
|
|
@@ -66,6 +75,9 @@ const stateModelFactory = (configSchema: AnyConfigurationSchemaType) =>
|
|
|
66
75
|
toggleShowLabels() {
|
|
67
76
|
self.trackShowLabels = !self.showLabels
|
|
68
77
|
},
|
|
78
|
+
toggleShowDescriptions() {
|
|
79
|
+
self.trackShowDescriptions = !self.showDescriptions
|
|
80
|
+
},
|
|
69
81
|
setDisplayMode(val: string) {
|
|
70
82
|
self.trackDisplayMode = val
|
|
71
83
|
},
|
|
@@ -100,6 +112,15 @@ const stateModelFactory = (configSchema: AnyConfigurationSchemaType) =>
|
|
|
100
112
|
self.toggleShowLabels()
|
|
101
113
|
},
|
|
102
114
|
},
|
|
115
|
+
{
|
|
116
|
+
label: 'Show descriptions',
|
|
117
|
+
icon: VisibilityIcon,
|
|
118
|
+
type: 'checkbox',
|
|
119
|
+
checked: self.showDescriptions,
|
|
120
|
+
onClick: () => {
|
|
121
|
+
self.toggleShowDescriptions()
|
|
122
|
+
},
|
|
123
|
+
},
|
|
103
124
|
{
|
|
104
125
|
label: 'Display mode',
|
|
105
126
|
icon: VisibilityIcon,
|
|
@@ -118,9 +139,10 @@ const stateModelFactory = (configSchema: AnyConfigurationSchemaType) =>
|
|
|
118
139
|
{
|
|
119
140
|
label: 'Set max height',
|
|
120
141
|
onClick: () => {
|
|
121
|
-
getSession(self).
|
|
122
|
-
|
|
123
|
-
|
|
142
|
+
getSession(self).queueDialog((doneCallback: Function) => [
|
|
143
|
+
SetMaxHeightDlg,
|
|
144
|
+
{ model: self, handleClose: doneCallback },
|
|
145
|
+
])
|
|
124
146
|
},
|
|
125
147
|
},
|
|
126
148
|
]
|
|
@@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'
|
|
|
3
3
|
import {
|
|
4
4
|
Button,
|
|
5
5
|
Dialog,
|
|
6
|
+
DialogActions,
|
|
6
7
|
DialogContent,
|
|
7
8
|
DialogTitle,
|
|
8
9
|
IconButton,
|
|
@@ -30,11 +31,11 @@ export default function ExportSvgDlg({
|
|
|
30
31
|
model: LGV
|
|
31
32
|
handleClose: () => void
|
|
32
33
|
}) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
)
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
const offscreenCanvas = typeof OffscreenCanvas !== 'undefined'
|
|
36
|
+
const [rasterizeLayers, setRasterizeLayers] = useState(offscreenCanvas)
|
|
36
37
|
const [loading, setLoading] = useState(false)
|
|
37
|
-
const [error, setError] = useState<
|
|
38
|
+
const [error, setError] = useState<unknown>()
|
|
38
39
|
const classes = useStyles()
|
|
39
40
|
return (
|
|
40
41
|
<Dialog open onClose={handleClose}>
|
|
@@ -53,8 +54,7 @@ export default function ExportSvgDlg({
|
|
|
53
54
|
<Typography display="inline">Creating SVG</Typography>
|
|
54
55
|
</div>
|
|
55
56
|
) : null}
|
|
56
|
-
|
|
57
|
-
{typeof OffscreenCanvas !== 'undefined' ? (
|
|
57
|
+
{offscreenCanvas ? (
|
|
58
58
|
<FormControlLabel
|
|
59
59
|
control={
|
|
60
60
|
<Checkbox
|
|
@@ -70,7 +70,15 @@ export default function ExportSvgDlg({
|
|
|
70
70
|
size may be large
|
|
71
71
|
</Typography>
|
|
72
72
|
)}
|
|
73
|
-
|
|
73
|
+
</DialogContent>
|
|
74
|
+
<DialogActions>
|
|
75
|
+
<Button
|
|
76
|
+
variant="contained"
|
|
77
|
+
color="secondary"
|
|
78
|
+
onClick={() => handleClose()}
|
|
79
|
+
>
|
|
80
|
+
Cancel
|
|
81
|
+
</Button>
|
|
74
82
|
<Button
|
|
75
83
|
variant="contained"
|
|
76
84
|
color="primary"
|
|
@@ -82,6 +90,7 @@ export default function ExportSvgDlg({
|
|
|
82
90
|
await model.exportSvg({ rasterizeLayers })
|
|
83
91
|
handleClose()
|
|
84
92
|
} catch (e) {
|
|
93
|
+
console.error(e)
|
|
85
94
|
setError(e)
|
|
86
95
|
} finally {
|
|
87
96
|
setLoading(false)
|
|
@@ -90,7 +99,7 @@ export default function ExportSvgDlg({
|
|
|
90
99
|
>
|
|
91
100
|
Submit
|
|
92
101
|
</Button>
|
|
93
|
-
</
|
|
102
|
+
</DialogActions>
|
|
94
103
|
</Dialog>
|
|
95
104
|
)
|
|
96
105
|
}
|