@apollo-annotation/jbrowse-plugin-apollo 0.3.8 → 0.3.10

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 (54) hide show
  1. package/dist/index.esm.js +10914 -10799
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +10979 -10865
  4. package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
  5. package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
  6. package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
  7. package/dist/jbrowse-plugin-apollo.umd.development.js +8799 -11326
  8. package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
  9. package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
  10. package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
  11. package/package.json +7 -7
  12. package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -1
  13. package/src/ApolloInternetAccount/model.ts +87 -65
  14. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +4 -4
  15. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +9 -7
  16. package/src/BackendDrivers/CollaborationServerDriver.ts +60 -23
  17. package/src/BackendDrivers/DesktopFileDriver.ts +2 -2
  18. package/src/ChangeManager.ts +22 -5
  19. package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -4
  20. package/src/FeatureDetailsWidget/NumberTextField.tsx +5 -2
  21. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +68 -212
  22. package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +92 -0
  23. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +6 -102
  24. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +33 -232
  25. package/src/LinearApolloDisplay/glyphs/util.ts +36 -0
  26. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +174 -0
  27. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.ts +200 -0
  28. package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +62 -386
  29. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +6 -0
  30. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +122 -70
  31. package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +33 -2
  32. package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +101 -3
  33. package/src/components/AddAssembly.tsx +34 -38
  34. package/src/components/AddFeature.tsx +21 -18
  35. package/src/components/AddRefSeqAliases.tsx +56 -42
  36. package/src/components/CopyFeature.tsx +1 -1
  37. package/src/components/CreateApolloAnnotation.tsx +22 -10
  38. package/src/components/DeleteAssembly.tsx +2 -9
  39. package/src/components/DownloadGFF3.tsx +2 -2
  40. package/src/components/ImportFeatures.tsx +1 -1
  41. package/src/components/ManageChecks.tsx +2 -9
  42. package/src/components/ManageUsers.tsx +23 -22
  43. package/src/components/OntologyTermAutocomplete.tsx +3 -10
  44. package/src/components/OntologyTermMultiSelect.tsx +2 -2
  45. package/src/components/ViewChangeLog.tsx +25 -50
  46. package/src/components/ViewCheckResults.tsx +1 -7
  47. package/src/config.ts +3 -3
  48. package/src/index.ts +17 -16
  49. package/src/makeDisplayComponent.tsx +9 -13
  50. package/src/session/ClientDataStore.ts +33 -15
  51. package/src/session/session.ts +23 -27
  52. package/src/util/displayUtils.ts +28 -0
  53. package/src/util/glyphUtils.ts +196 -1
  54. package/src/util/loadAssemblyIntoClient.ts +3 -2
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable @typescript-eslint/unbound-method */
2
- /* eslint-disable @typescript-eslint/no-unnecessary-condition */
3
2
 
4
3
  import { type AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
5
4
  import { AddFeatureChange } from '@apollo-annotation/shared'
@@ -26,6 +25,7 @@ import {
26
25
  import ObjectID from 'bson-objectid'
27
26
  import React, { useState } from 'react'
28
27
 
28
+ import { CollaborationServerDriver } from '../BackendDrivers'
29
29
  import { type ChangeManager } from '../ChangeManager'
30
30
  import { isOntologyClass } from '../OntologyManager'
31
31
  import { type ApolloSessionModel } from '../session'
@@ -96,30 +96,32 @@ export function AddFeature({
96
96
  const [end, setEnd] = useState(String(region.end))
97
97
  const [start, setStart] = useState(String(region.start + 1))
98
98
  const [type, setType] = useState<NewFeature>(NewFeature.GENE_AND_SUBFEATURES)
99
- const [customType, setCustomType] = useState<string>()
99
+ const [customType, setCustomType] = useState<string>('')
100
100
  const [strand, setStrand] = useState<1 | -1 | undefined>()
101
101
  const [errorMessage, setErrorMessage] = useState('')
102
102
 
103
- function onSubmit(event: React.FormEvent<HTMLFormElement>) {
103
+ async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
104
104
  event.preventDefault()
105
105
  setErrorMessage('')
106
106
 
107
- let refSeqId
108
- for (const [, asm] of session.apolloDataStore.assemblies ?? new Map()) {
109
- if (asm._id === region.assemblyName) {
110
- for (const [, refseq] of asm.refSeqs ?? new Map()) {
111
- if (refseq.name === region.refName) {
112
- refSeqId = refseq._id
113
- }
114
- }
115
- }
107
+ const backendDriver = session.apolloDataStore.getBackendDriver(
108
+ region.assemblyName,
109
+ )
110
+ if (!backendDriver) {
111
+ setErrorMessage('No backend driver found')
112
+ return
116
113
  }
117
-
118
- if (!refSeqId) {
119
- setErrorMessage(
120
- 'Invalid refseq id. Make sure you have the Apollo annotation track open',
114
+ let refSeqId = region.refName
115
+ if (backendDriver instanceof CollaborationServerDriver) {
116
+ const backendRefSeqId = await backendDriver.getRefSeqId(
117
+ region.assemblyName,
118
+ region.refName,
121
119
  )
122
- return
120
+ if (!backendRefSeqId) {
121
+ setErrorMessage(`Could not find refSeq for "${region.refName}"`)
122
+ return
123
+ }
124
+ refSeqId = backendRefSeqId
123
125
  }
124
126
 
125
127
  if (type === NewFeature.GENE_AND_SUBFEATURES) {
@@ -248,6 +250,7 @@ export function AddFeature({
248
250
  maxWidth={false}
249
251
  data-testid="add-feature-dialog"
250
252
  >
253
+ {/* eslint-disable-next-line @typescript-eslint/no-misused-promises */}
251
254
  <form onSubmit={onSubmit} data-testid="submit-form">
252
255
  <DialogContent style={{ display: 'flex', flexDirection: 'column' }}>
253
256
  <TextField
@@ -344,7 +347,7 @@ export function AddFeature({
344
347
  session={session}
345
348
  ontologyName="Sequence Ontology"
346
349
  style={{ width: 170 }}
347
- value=""
350
+ value={customType}
348
351
  filterTerms={isOntologyClass}
349
352
  renderInput={(params) => (
350
353
  <TextField
@@ -16,12 +16,19 @@ import {
16
16
  Select,
17
17
  type SelectChangeEvent,
18
18
  } from '@mui/material'
19
- import { DataGrid, type GridColDef, type GridRowModel } from '@mui/x-data-grid'
19
+ import {
20
+ DataGrid,
21
+ type GridColDef,
22
+ type GridRowModel,
23
+ type GridRowSelectionModel,
24
+ } from '@mui/x-data-grid'
25
+ import { observer } from 'mobx-react'
20
26
  import React, { useEffect, useRef, useState } from 'react'
21
27
 
22
28
  import {
23
29
  type ApolloInternetAccount,
24
30
  type CollaborationServerDriver,
31
+ type RefNameAliases,
25
32
  } from '../BackendDrivers'
26
33
  import { type ChangeManager } from '../ChangeManager'
27
34
  import { type ApolloSessionModel } from '../session'
@@ -30,7 +37,7 @@ import { Dialog } from './Dialog'
30
37
 
31
38
  const columns: GridColDef[] = [
32
39
  { field: 'refName', headerName: 'Ref Name' },
33
- { field: 'aliases', headerName: 'Aliases', editable: true },
40
+ { field: 'aliases', headerName: 'Aliases', editable: true, flex: 1 },
34
41
  ]
35
42
 
36
43
  interface AddChildFeatureProps {
@@ -44,7 +51,7 @@ const isGeneratedObjectId = (key: string): boolean => {
44
51
  return pattern.test(key)
45
52
  }
46
53
 
47
- export function AddRefSeqAliases({
54
+ export const AddRefSeqAliases = observer(function AddRefSeqAliases({
48
55
  changeManager,
49
56
  handleClose,
50
57
  session,
@@ -75,44 +82,50 @@ export function AddRefSeqAliases({
75
82
  const assemblies = collaborationServerDriver.getAssemblies()
76
83
 
77
84
  useEffect(() => {
78
- let retry = 0
79
- const maxRetries = 2
80
- const initializeRefNameAliasMap = () => {
81
- if (!selectedAssembly) {
82
- return
83
- }
84
- const initialMap = new Map<string, string[]>()
85
- if (retry < maxRetries && !selectedAssembly.refNames) {
86
- retry++
87
- setTimeout(initializeRefNameAliasMap, 50)
88
- }
89
- if (!selectedAssembly.refNames) {
90
- return
91
- }
92
- const refNameAliasess = selectedAssembly.refNameAliases
93
- for (const key in refNameAliasess) {
94
- const value = refNameAliasess[key]
95
- if (!value || isGeneratedObjectId(key)) {
96
- continue
97
- }
98
- if (initialMap.has(value)) {
99
- const aliases = initialMap.get(value) ?? []
100
- initialMap.set(value, [...aliases, key])
101
- } else {
102
- initialMap.set(value, [key])
103
- }
104
- }
105
- setRefNameAliasMap(initialMap)
85
+ if (assemblies.length > 0) {
86
+ setSelectedAssembly(assemblies[0])
87
+ collaborationServerDriver
88
+ .getRefNameAliases(assemblies[0].name)
89
+ .then((refNameAliases) => {
90
+ initializeRefNameAliasMap(refNameAliases)
91
+ })
92
+ .catch(() => {
93
+ setRefNameAliasMap(new Map())
94
+ setErrorMessage('Error fetching refName aliases for assembly')
95
+ })
106
96
  }
97
+ // eslint-disable-next-line react-hooks/exhaustive-deps
98
+ }, [])
107
99
 
108
- initializeRefNameAliasMap()
109
- }, [selectedAssembly])
100
+ const initializeRefNameAliasMap = (refNameAliasesList: RefNameAliases[]) => {
101
+ const initialMap = new Map<string, string[]>()
102
+ for (const refNameAliases of refNameAliasesList) {
103
+ const key = refNameAliases.refName
104
+ if (isGeneratedObjectId(key)) {
105
+ continue
106
+ }
107
+ initialMap.set(key, refNameAliases.aliases)
108
+ }
109
+ setRefNameAliasMap(initialMap)
110
+ }
110
111
 
111
112
  const handleChangeAssembly = (e: SelectChangeEvent) => {
112
113
  const newAssembly = assemblies.find((asm) => asm.name === e.target.value)
113
114
  setSelectedAssembly(newAssembly)
115
+ if (!newAssembly?.name) {
116
+ return
117
+ }
118
+ collaborationServerDriver
119
+ .getRefNameAliases(newAssembly.name)
120
+ .then((refNameAliases) => {
121
+ initializeRefNameAliasMap(refNameAliases)
122
+ setErrorMessage('')
123
+ })
124
+ .catch(() => {
125
+ setRefNameAliasMap(new Map())
126
+ setErrorMessage('Error fetching refName aliases for assembly')
127
+ })
114
128
  setEnableSubmit(false)
115
- setErrorMessage('')
116
129
  if (fileRef.current) {
117
130
  fileRef.current.value = ''
118
131
  }
@@ -145,11 +158,12 @@ export function AddRefSeqAliases({
145
158
  })
146
159
  }
147
160
 
148
- const rowSelectionChange = (ids: number[]) => {
149
- if (ids.length > 0) {
161
+ const rowSelectionChange = (gridRowSelectionModel: GridRowSelectionModel) => {
162
+ const { ids } = gridRowSelectionModel
163
+ if (ids.size > 0) {
150
164
  setEnableSubmit(true)
151
- const selectedRows = ids.flatMap((id) =>
152
- getTableRows().filter((row) => row.id === id),
165
+ const selectedRows = [...ids.values()].flatMap((id) =>
166
+ getTableRows().filter((row) => String(row.id) === String(id)),
153
167
  )
154
168
  setSelectedRows(selectedRows)
155
169
  } else {
@@ -222,6 +236,7 @@ export function AddRefSeqAliases({
222
236
  label="Assembly"
223
237
  value={selectedAssembly?.name ?? ''}
224
238
  onChange={handleChangeAssembly}
239
+ style={{ minWidth: 150 }}
225
240
  >
226
241
  {assemblies.map((option) => (
227
242
  <MenuItem key={option.name} value={option.name}>
@@ -255,11 +270,10 @@ export function AddRefSeqAliases({
255
270
  },
256
271
  }}
257
272
  pageSizeOptions={[5, 10]}
258
- onRowSelectionModelChange={(ids) => {
259
- rowSelectionChange(ids as unknown as number[])
260
- }}
273
+ onRowSelectionModelChange={rowSelectionChange}
261
274
  processRowUpdate={processRowUpdate}
262
275
  checkboxSelection
276
+ disableRowSelectionExcludeModel
263
277
  ></DataGrid>
264
278
  </div>
265
279
  ) : null}
@@ -284,4 +298,4 @@ export function AddRefSeqAliases({
284
298
  ) : null}
285
299
  </Dialog>
286
300
  )
287
- }
301
+ })
@@ -99,8 +99,8 @@ export function CopyFeature({
99
99
  }
100
100
 
101
101
  useEffect(() => {
102
- setSelectedRefSeqId('')
103
102
  async function getRefNames() {
103
+ setSelectedRefSeqId('')
104
104
  if (!selectedAssemblyId) {
105
105
  setErrorMessage('No assemblies to copy to')
106
106
  return
@@ -193,11 +193,8 @@ export function CreateApolloAnnotation({
193
193
  continue
194
194
  }
195
195
 
196
- // Destination feature should be of type gene amd should be on the same strand as the source feature
197
- if (
198
- featureTypeOntology?.isTypeOf(f.type, 'gene') &&
199
- f.strand === annotationFeature.strand
200
- ) {
196
+ // Destination feature should be of type gene
197
+ if (featureTypeOntology?.isTypeOf(f.type, 'gene')) {
201
198
  const featureSnapshot = getSnapshot(f)
202
199
  filteredFeatures.push(featureSnapshot)
203
200
  }
@@ -373,7 +370,7 @@ export function CreateApolloAnnotation({
373
370
  })
374
371
  }
375
372
 
376
- await submitChange(change)
373
+ await submitChange(change, annotationFeature._id)
377
374
  }
378
375
 
379
376
  const copyTranscriptsToDestinationGene = async (
@@ -384,6 +381,15 @@ export function CreateApolloAnnotation({
384
381
  }
385
382
  for (const transcriptId of Object.keys(transcripts)) {
386
383
  const transcript = transcripts[transcriptId]
384
+ transcript.strand = selectedDestinationFeature.strand
385
+
386
+ // update strand of transcript children if they exist
387
+ if (transcript.children) {
388
+ for (const childId of Object.keys(transcript.children)) {
389
+ transcript.children[childId].strand =
390
+ selectedDestinationFeature.strand
391
+ }
392
+ }
387
393
  const change = new AddFeatureChange({
388
394
  parentFeatureId: selectedDestinationFeature._id,
389
395
  changedIds: [selectedDestinationFeature._id],
@@ -391,7 +397,8 @@ export function CreateApolloAnnotation({
391
397
  assembly: assembly.name,
392
398
  addedFeature: transcript,
393
399
  })
394
- await submitChange(change)
400
+ // selects the last added transcript
401
+ await submitChange(change, transcriptId)
395
402
  }
396
403
  }
397
404
 
@@ -419,8 +426,7 @@ export function CreateApolloAnnotation({
419
426
  },
420
427
  },
421
428
  })
422
- await submitChange(change)
423
- apolloSessionModel.apolloSetSelectedFeature(newGeneId)
429
+ await submitChange(change, newGeneId)
424
430
  }
425
431
 
426
432
  const extendSelectedDestinationFeatureLocation = async (
@@ -462,8 +468,14 @@ export function CreateApolloAnnotation({
462
468
 
463
469
  const submitChange = async (
464
470
  change: AddFeatureChange | LocationStartChange | LocationEndChange,
471
+ selectedFeatureId?: string,
465
472
  ) => {
466
- await apolloSessionModel.apolloDataStore.changeManager.submit(change)
473
+ await apolloSessionModel.apolloDataStore.changeManager
474
+ .submit(change)
475
+ .then(() => {
476
+ // Selects the newly added/modified feature
477
+ apolloSessionModel.apolloSetSelectedFeature(selectedFeatureId)
478
+ })
467
479
  }
468
480
 
469
481
  const handleCreateNewGeneChange = (
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/unbound-method */
2
2
  /* eslint-disable @typescript-eslint/no-misused-promises */
3
3
  import { DeleteAssemblyChange } from '@apollo-annotation/shared'
4
- import { type Assembly } from '@jbrowse/core/assemblyManager/assembly'
5
4
  import {
6
5
  Button,
7
6
  Checkbox,
@@ -15,7 +14,7 @@ import {
15
14
  type SelectChangeEvent,
16
15
  } from '@mui/material'
17
16
  import { getRoot } from 'mobx-state-tree'
18
- import React, { useEffect, useState } from 'react'
17
+ import React, { useState } from 'react'
19
18
 
20
19
  import { type ApolloInternetAccountModel } from '../ApolloInternetAccount/model'
21
20
  import {
@@ -40,7 +39,6 @@ export function DeleteAssembly({
40
39
  session,
41
40
  }: DeleteAssemblyProps) {
42
41
  const { internetAccounts } = getRoot<ApolloRootModel>(session)
43
- const [selectedAssembly, setSelectedAssembly] = useState<Assembly>()
44
42
  const [errorMessage, setErrorMessage] = useState('')
45
43
  const [confirmDelete, setconfirmDelete] = useState(false)
46
44
  const [submitted, setSubmitted] = useState(false)
@@ -63,12 +61,7 @@ export function DeleteAssembly({
63
61
  }
64
62
 
65
63
  const assemblies = collaborationServerDriver.getAssemblies()
66
-
67
- useEffect(() => {
68
- if (assemblies.length > 0 && selectedAssembly === undefined) {
69
- setSelectedAssembly(assemblies[0])
70
- }
71
- }, [assemblies, selectedAssembly])
64
+ const [selectedAssembly, setSelectedAssembly] = useState(assemblies.at(0))
72
65
 
73
66
  function handleChangeInternetAccount(e: SelectChangeEvent) {
74
67
  setSubmitted(false)
@@ -5,7 +5,7 @@
5
5
  /* eslint-disable @typescript-eslint/no-misused-promises */
6
6
  import { type ApolloAssembly } from '@apollo-annotation/mst'
7
7
  import { annotationFeatureToGFF3 } from '@apollo-annotation/shared'
8
- import gff, { type GFF3Item } from '@gmod/gff'
8
+ import { type GFF3Item, formatSync } from '@gmod/gff'
9
9
  import { type Assembly } from '@jbrowse/core/assemblyManager/assembly'
10
10
  import { getConf } from '@jbrowse/core/configuration'
11
11
  import {
@@ -169,7 +169,7 @@ export function DownloadGFF3({ handleClose, session }: DownloadGFF3Props) {
169
169
  const { refName, seq } = sequenceFeature
170
170
  gff3Items.push({ id: refName, description: '', sequence: seq })
171
171
  }
172
- const gff3 = gff.formatSync(gff3Items)
172
+ const gff3 = formatSync(gff3Items)
173
173
  const gff3Blob = new Blob([gff3], { type: 'text/plain;charset=utf-8' })
174
174
  saveAs(
175
175
  gff3Blob,
@@ -182,7 +182,7 @@ export function ImportFeatures({
182
182
  statusMessage: 'Uploading file, this may take awhile',
183
183
  progressPct: 0,
184
184
  cancelCallback: () => {
185
- controller.abort()
185
+ controller.abort('ImportFeatures')
186
186
  jobsManager.abortJob(job.name)
187
187
  },
188
188
  }
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
2
2
  /* eslint-disable @typescript-eslint/unbound-method */
3
3
  /* eslint-disable @typescript-eslint/no-misused-promises */
4
- import { type Assembly } from '@jbrowse/core/assemblyManager/assembly'
5
4
  import { type AbstractSessionModel } from '@jbrowse/core/util'
6
5
  import {
7
6
  Button,
@@ -52,7 +51,6 @@ interface CheckDocument {
52
51
 
53
52
  export function ManageChecks({ handleClose, session }: ManageChecksProps) {
54
53
  const { internetAccounts } = getRoot<ApolloRootModel>(session)
55
- const [selectedAssembly, setSelectedAssembly] = useState<Assembly>()
56
54
  const [errorMessage, setErrorMessage] = useState('')
57
55
  const [submitted, setSubmitted] = useState(false)
58
56
  const apolloInternetAccounts = internetAccounts.filter(
@@ -76,6 +74,7 @@ export function ManageChecks({ handleClose, session }: ManageChecksProps) {
76
74
  }
77
75
 
78
76
  const assemblies = collaborationServerDriver.getAssemblies()
77
+ const [selectedAssembly, setSelectedAssembly] = useState(assemblies.at(0))
79
78
 
80
79
  useEffect(() => {
81
80
  async function getChecks() {
@@ -99,19 +98,13 @@ export function ManageChecks({ handleClose, session }: ManageChecksProps) {
99
98
  })
100
99
  }, [selectedInternetAccount])
101
100
 
102
- useEffect(() => {
103
- if (assemblies.length > 0 && selectedAssembly === undefined) {
104
- setSelectedAssembly(assemblies[0])
105
- }
106
- }, [assemblies, selectedAssembly])
107
-
108
101
  useEffect(() => {
109
102
  async function getChecks() {
110
103
  if (!selectedAssembly) {
111
104
  return
112
105
  }
113
106
  const { baseURL, getFetcher } = selectedInternetAccount
114
- const uri = new URL(`/assemblies/${selectedAssembly.name}`, baseURL).href
107
+ const uri = new URL(`assemblies/${selectedAssembly.name}`, baseURL).href
115
108
  const apolloFetch = getFetcher({ locationType: 'UriLocation', uri })
116
109
  const response = await apolloFetch(uri, { method: 'GET' })
117
110
  if (!response.ok) {
@@ -28,7 +28,7 @@ import {
28
28
  GridToolbar,
29
29
  } from '@mui/x-data-grid'
30
30
  import { getRoot } from 'mobx-state-tree'
31
- import React, { useCallback, useEffect, useState } from 'react'
31
+ import React, { useEffect, useState } from 'react'
32
32
 
33
33
  import { type ApolloInternetAccountModel } from '../ApolloInternetAccount/model'
34
34
  import { type ChangeManager } from '../ChangeManager'
@@ -72,33 +72,34 @@ export function ManageUsers({
72
72
  )
73
73
  const [users, setUsers] = useState<UserResponse[]>([])
74
74
 
75
- const getUsers = useCallback(async () => {
76
- const { baseURL } = selectedInternetAccount
77
- const uri = new URL('users', baseURL).href
78
- const apolloFetch = selectedInternetAccount.getFetcher({
79
- locationType: 'UriLocation',
80
- uri,
81
- })
82
- if (apolloFetch) {
83
- const response = await apolloFetch(uri, { method: 'GET' })
84
- if (!response.ok) {
85
- const newErrorMessage = await createFetchErrorMessage(
86
- response,
87
- 'Error when getting user data from db',
75
+ useEffect(() => {
76
+ async function getUsers() {
77
+ const { baseURL } = selectedInternetAccount
78
+ const uri = new URL('users', baseURL).href
79
+ const apolloFetch = selectedInternetAccount.getFetcher({
80
+ locationType: 'UriLocation',
81
+ uri,
82
+ })
83
+ if (apolloFetch) {
84
+ const response = await apolloFetch(uri, { method: 'GET' })
85
+ if (!response.ok) {
86
+ const newErrorMessage = await createFetchErrorMessage(
87
+ response,
88
+ 'Error when getting user data from db',
89
+ )
90
+ setErrorMessage(newErrorMessage)
91
+ return
92
+ }
93
+ const data = (await response.json()) as UserResponse[]
94
+ setUsers(
95
+ data.map((u) => (u.role === undefined ? { ...u, role: '' } : u)),
88
96
  )
89
- setErrorMessage(newErrorMessage)
90
- return
91
97
  }
92
- const data = (await response.json()) as UserResponse[]
93
- setUsers(data.map((u) => (u.role === undefined ? { ...u, role: '' } : u)))
94
98
  }
95
- }, [selectedInternetAccount])
96
-
97
- useEffect(() => {
98
99
  getUsers().catch((error) => {
99
100
  setErrorMessage(String(error))
100
101
  })
101
- }, [getUsers])
102
+ }, [selectedInternetAccount])
102
103
 
103
104
  async function deleteUser(id: GridRowId) {
104
105
  const change = new DeleteUserChange({
@@ -73,21 +73,14 @@ export function OntologyTermAutocomplete({
73
73
  [filterTermsProp, includeDeprecated],
74
74
  )
75
75
 
76
- // effect for clearing choices when not open
77
- useEffect(() => {
78
- if (!open) {
79
- setTermChoices(undefined)
80
- }
81
- }, [open])
82
-
83
76
  // effect for matching the current value with an ontology term
84
77
  useEffect(() => {
85
78
  const controller = new AbortController()
86
79
  const { signal } = controller
87
80
  if (needToLoadCurrentTerm) {
88
- setCurrentOntologyTermInvalid('')
89
81
  getCurrentTerm(ontologyStore, valueString, filterTerms, signal).then(
90
82
  (term) => {
83
+ setCurrentOntologyTermInvalid('')
91
84
  if (!signal.aborted) {
92
85
  setCurrentOntologyTerm(term)
93
86
  }
@@ -100,7 +93,7 @@ export function OntologyTermAutocomplete({
100
93
  )
101
94
  }
102
95
  return () => {
103
- controller.abort()
96
+ controller.abort('OntologyTermAutocomplete matcher')
104
97
  }
105
98
  }, [session, valueString, filterTerms, ontologyStore, needToLoadCurrentTerm])
106
99
 
@@ -126,7 +119,7 @@ export function OntologyTermAutocomplete({
126
119
  )
127
120
  }
128
121
  return () => {
129
- controller.abort()
122
+ controller.abort('OntologyTermAutocomplete loader')
130
123
  }
131
124
  }, [
132
125
  needToLoadTermChoices,
@@ -89,7 +89,7 @@ function TermTagWithTooltip({
89
89
  })
90
90
 
91
91
  return () => {
92
- controller.abort()
92
+ controller.abort('TermTagWithTooltip ')
93
93
  }
94
94
  }, [termId, ontology, manager])
95
95
 
@@ -211,7 +211,7 @@ export function OntologyTermMultiSelect({
211
211
  })
212
212
 
213
213
  return () => {
214
- aborter.abort()
214
+ aborter.abort('OntologyTermMultiSelect')
215
215
  }
216
216
  }, [getOntologyTerms, ontology, includeDeprecated, inputValue, value])
217
217