diff --git a/jbrowse_config.json b/jbrowse_config.json
index 2f917bb..7dc69a7 100644
--- a/jbrowse_config.json
+++ b/jbrowse_config.json
@@ -1,4 +1,197 @@
{
+ "assemblies": [
+ {
+ "name": "volvox",
+ "aliases": [
+ "vvx"
+ ],
+ "sequence": {
+ "type": "ReferenceSequenceTrack",
+ "trackId": "volvox_refseq",
+ "metadata": {
+ "date": "2020-08-20"
+ },
+ "formatAbout": {
+ "hideUris": true,
+ "config": "jexl:{extraField:'important data'}"
+ },
+ "adapter": {
+ "type": "TwoBitAdapter",
+ "twoBitLocation": {
+ "uri": "test_data/volvox/volvox.2bit",
+ "locationType": "UriLocation"
+ }
+ }
+ },
+ "refNameAliases": {
+ "adapter": {
+ "type": "FromConfigAdapter",
+ "adapterId": "W6DyPGJ0UU",
+ "features": [
+ {
+ "refName": "ctgA",
+ "uniqueId": "alias1",
+ "aliases": [
+ "A",
+ "contigA"
+ ]
+ },
+ {
+ "refName": "ctgB",
+ "uniqueId": "alias2",
+ "aliases": [
+ "B",
+ "contigB"
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "volvox_tripalauth",
+ "sequence": {
+ "type": "ReferenceSequenceTrack",
+ "trackId": "volvox_tripalauth-ReferenceSequenceTrack",
+ "adapter": {
+ "type": "TwoBitAdapter",
+ "twoBitLocation": {
+ "uri": "test_data/volvox/volvox.2bit",
+ "locationType": "UriLocation",
+ "internetAccountId": "customTripalAuth"
+ }
+ }
+ }
+ }
+ ],
+ "connections": [],
+ "defaultSession": {
+ "name": "Integration test example",
+ "views": [
+ {
+ "id": "integration_test",
+ "type": "LinearGenomeView",
+ "offsetPx": 2000,
+ "bpPerPx": 0.05,
+ "displayedRegions": [
+ {
+ "refName": "ctgA",
+ "start": 0,
+ "end": 50001,
+ "assemblyName": "volvox"
+ }
+ ]
+ }
+ ],
+ "widgets": {
+ "hierarchicalTrackSelector": {
+ "id": "hierarchicalTrackSelector",
+ "type": "HierarchicalTrackSelectorWidget",
+ "filterText": "",
+ "view": "integration_test"
+ }
+ },
+ "activeWidgets": {
+ "hierarchicalTrackSelector": "hierarchicalTrackSelector"
+ }
+ },
+ "tracks": [
+ {
+ "type": "QuantitativeTrack",
+ "trackId": "tripalauth_bigwig",
+ "name": "TripalAuth BigWig",
+ "category": [
+ "Authentication"
+ ],
+ "assemblyNames": [
+ "volvox"
+ ],
+ "adapter": {
+ "type": "BigWigAdapter",
+ "bigWigLocation": {
+ "locationType": "UriLocation",
+ "uri": "test_data/volvox/volvox.bw",
+ "internetAccountId": "ActivatingCrops"
+ }
+ }
+ },
+ {
+ "type": "VariantTrack",
+ "trackId": "tripalauth_vcf",
+ "name": "TripalAuth VCF",
+ "assemblyNames": [
+ "volvox"
+ ],
+ "category": [
+ "Authentication"
+ ],
+ "adapter": {
+ "type": "VcfTabixAdapter",
+ "vcfGzLocation": {
+ "uri": "test_data/volvox/volvox.filtered.vcf.gz",
+ "locationType": "UriLocation",
+ "internetAccountId": "ActivatingCrops"
+ },
+ "index": {
+ "location": {
+ "uri": "test_data/volvox/volvox.filtered.vcf.gz.tbi",
+ "locationType": "UriLocation",
+ "internetAccountId": "ActivatingCrops"
+ }
+ }
+ }
+ },
+ {
+ "type": "QuantitativeTrack",
+ "trackId": "noauth_bigwig",
+ "name": "NoAuth BigWig",
+ "category": [
+ "Authentication"
+ ],
+ "assemblyNames": [
+ "volvox"
+ ],
+ "adapter": {
+ "type": "BigWigAdapter",
+ "bigWigLocation": {
+ "locationType": "UriLocation",
+ "uri": "test_data/volvox/volvox.bw"
+ }
+ }
+ },
+ {
+ "type": "VariantTrack",
+ "trackId": "noauth_vcf",
+ "name": "NoAuth VCF",
+ "assemblyNames": [
+ "volvox"
+ ],
+ "category": [
+ "Authentication"
+ ],
+ "adapter": {
+ "type": "VcfTabixAdapter",
+ "vcfGzLocation": {
+ "uri": "test_data/volvox/volvox.filtered.vcf.gz",
+ "locationType": "UriLocation"
+ },
+ "index": {
+ "location": {
+ "uri": "test_data/volvox/volvox.filtered.vcf.gz.tbi",
+ "locationType": "UriLocation"
+ }
+ }
+ }
+ }
+ ],
+ "internetAccounts": [
+ {
+ "type": "DrupalRestAuthModel",
+ "internetAccountId": "ActivatingCrops",
+ "name": "Activating Crops Tripal Authentication",
+ "description": "Requires login to the Activating Crops website"
+ }
+ ],
"plugins": [
{
"name": "DrupalRestAuthModel",
diff --git a/src/DrupalRestAuthModel/DrupalRestAuthLoginForm.tsx b/src/DrupalRestAuthModel/DrupalRestAuthLoginForm.tsx
new file mode 100644
index 0000000..c5bc571
--- /dev/null
+++ b/src/DrupalRestAuthModel/DrupalRestAuthLoginForm.tsx
@@ -0,0 +1,68 @@
+import React, { useState } from 'react'
+import { Button, DialogContent, DialogActions, TextField } from '@mui/material'
+import { Dialog } from '@jbrowse/core/ui'
+
+export function DrupalRestAuthLoginForm({
+ internetAccountId,
+ handleClose,
+}: {
+ internetAccountId: string
+ handleClose: (arg?: string) => void
+}) {
+ const [username, setUsername] = useState('')
+ const [password, setPassword] = useState('')
+
+ return (
+
+ )
+}
diff --git a/src/DrupalRestAuthModel/configSchema.ts b/src/DrupalRestAuthModel/configSchema.ts
new file mode 100644
index 0000000..c4b0619
--- /dev/null
+++ b/src/DrupalRestAuthModel/configSchema.ts
@@ -0,0 +1,43 @@
+import { ConfigurationSchema } from '@jbrowse/core/configuration'
+import { Instance } from 'mobx-state-tree'
+import { BaseInternetAccountConfig } from '@jbrowse/core/pluggableElementTypes/models'
+
+/**
+ * #config DrupalRestAuthModel
+ */
+function x() { } // eslint-disable-line @typescript-eslint/no-unused-vars
+
+const DrupalRestConfigSchema = ConfigurationSchema(
+ 'DrupalRestAuthInternetAccount',
+ {
+ /**
+ * #slot
+ */
+ tokenType: {
+ description: 'a custom name for a token to include in the header',
+ type: 'string',
+ defaultValue: 'Basic',
+ },
+ /**
+ * #slot
+ */
+ validateWithHEAD: {
+ description: 'validate the token with a HEAD request before using it',
+ type: 'boolean',
+ defaultValue: true,
+ },
+ },
+ {
+ /**
+ * #baseConfiguration
+ */
+ baseConfiguration: BaseInternetAccountConfig,
+ explicitlyTyped: true,
+ },
+)
+
+export type DrupalRestAuthInternetAccountConfigModel = typeof DrupalRestConfigSchema
+
+export type DrupalRestAuthInternetAccountConfig =
+ Instance
+export default DrupalRestConfigSchema
diff --git a/src/DrupalRestAuthModel/model.tsx b/src/DrupalRestAuthModel/model.tsx
new file mode 100644
index 0000000..947f231
--- /dev/null
+++ b/src/DrupalRestAuthModel/model.tsx
@@ -0,0 +1,112 @@
+import { ConfigurationReference, getConf } from '@jbrowse/core/configuration'
+import { InternetAccount } from '@jbrowse/core/pluggableElementTypes/models'
+import { UriLocation } from '@jbrowse/core/util/types'
+import { Instance, types, getRoot } from 'mobx-state-tree'
+
+// locals
+import { DrupalRestAuthInternetAccountConfigModel } from './configSchema'
+import { DrupalRestAuthLoginForm } from './DrupalRestAuthLoginForm'
+// import { getResponseError } from '../util'
+async function getError(response: Response) {
+ try {
+ return response.text()
+ } catch (e) {
+ return response.statusText
+ }
+}
+
+async function getResponseError({
+ response,
+ reason,
+ statusText,
+}: {
+ response: Response
+ reason?: string
+ statusText?: string
+}) {
+ return [
+ `HTTP ${response.status}`,
+ reason,
+ statusText ?? (await getError(response)),
+ ]
+ .filter(f => !!f)
+ .join(' - ')
+}
+
+
+/**
+ * #stateModel DrupalRestAuthInternetAccount
+ */
+const stateModelFactory = (
+ configSchema: DrupalRestAuthInternetAccountConfigModel,
+) => {
+ return InternetAccount.named('DrupalRestAuthInternetAccount')
+ .props({
+ /**
+ * #property
+ */
+ type: types.literal('DrupalRestAuthInternetAccount'),
+ /**
+ * #property
+ */
+ configuration: ConfigurationReference(configSchema),
+ })
+ .views(self => ({
+ /**
+ * #getter
+ */
+ get validateWithHEAD(): boolean {
+ return getConf(self, 'validateWithHEAD')
+ },
+ }))
+ .actions(self => ({
+ /**
+ * #action
+ */
+ getTokenFromUser(
+ resolve: (token: string) => void,
+ reject: (error: Error) => void,
+ ) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const { session } = getRoot(self)
+ session.queueDialog((doneCallback: () => void) => [
+ DrupalRestAuthLoginForm,
+ {
+ internetAccountId: self.internetAccountId,
+ handleClose: (token: string) => {
+ if (token) {
+ resolve(token)
+ } else {
+ reject(new Error('User cancelled entry'))
+ }
+ doneCallback()
+ },
+ },
+ ])
+ },
+ /**
+ * #action
+ */
+ async validateToken(token: string, location: UriLocation) {
+ console.log('here!!!:)')
+ if (!self.validateWithHEAD) {
+ return token
+ }
+ const newInit = self.addAuthHeaderToInit({ method: 'HEAD' }, token)
+ const response = await fetch(location.uri, newInit)
+ if (!response.ok) {
+ throw new Error(
+ await getResponseError({
+ response,
+ reason: 'Error validating token',
+ }),
+ )
+ }
+ return token
+ },
+ }))
+}
+
+export default stateModelFactory
+export type DrupalRestAuthStateModel = ReturnType
+export type DrupalRestAuthModel = Instance
diff --git a/src/HelloView/components/HelloView.test.tsx b/src/HelloView/components/HelloView.test.tsx
deleted file mode 100644
index be64509..0000000
--- a/src/HelloView/components/HelloView.test.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react'
-import { render, fireEvent, screen } from '@testing-library/react'
-import '@testing-library/jest-dom'
-import HelloView from './HelloView'
-
-it('renders and reacts to button push', async () => {
- render()
-
- expect(screen.getByRole('heading')).toHaveTextContent(
- 'Hello plugin developers!',
- )
-
- fireEvent.click(screen.getByText('Push the button'))
- await screen.findByText('Whoa! You pushed the button!')
-})
diff --git a/src/HelloView/components/HelloView.tsx b/src/HelloView/components/HelloView.tsx
deleted file mode 100644
index 6cec198..0000000
--- a/src/HelloView/components/HelloView.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React, { useState } from 'react'
-
-export default function ReactComponent() {
- const [pushed, setPushed] = useState('')
- return (
-
-
Hello plugin developers!
-
-
{pushed}
-
- )
-}
diff --git a/src/HelloView/index.ts b/src/HelloView/index.ts
deleted file mode 100644
index 4dbfdab..0000000
--- a/src/HelloView/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as ReactComponent } from './components/HelloView'
-export { default as stateModel } from './stateModel'
diff --git a/src/HelloView/stateModel.ts b/src/HelloView/stateModel.ts
deleted file mode 100644
index 14669fa..0000000
--- a/src/HelloView/stateModel.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { ElementId } from '@jbrowse/core/util/types/mst'
-import { types } from 'mobx-state-tree'
-
-const stateModel = types
- .model({
- id: ElementId,
- type: types.literal('HelloView'),
- })
- .actions(() => ({
- // unused but required by your view
- setWidth() {},
- }))
-
-export default stateModel
diff --git a/src/index.ts b/src/index.ts
index e7d682a..ef3ecbd 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,21 +3,21 @@ import PluginManager from '@jbrowse/core/PluginManager'
import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'
import { AbstractSessionModel, isAbstractMenuManager } from '@jbrowse/core/util'
import { version } from '../package.json'
-import {
- ReactComponent as HelloViewReactComponent,
- stateModel as helloViewStateModel,
-} from './HelloView'
+import { InternetAccountType } from '@jbrowse/core/pluggableElementTypes'
+import configSchema from './DrupalRestAuthModel/configSchema'
+import modelFactory from './DrupalRestAuthModel/model'
export default class DrupalRestAuthModelPlugin extends Plugin {
name = 'DrupalRestAuthModelPlugin'
version = version
install(pluginManager: PluginManager) {
- pluginManager.addViewType(() => {
- return new ViewType({
- name: 'HelloView',
- stateModel: helloViewStateModel,
- ReactComponent: HelloViewReactComponent,
+ console.log('here')
+ pluginManager.addInternetAccountType(() => {
+ return new InternetAccountType({
+ name: 'DrupalRestAuthInternetAccount',
+ configSchema,
+ stateModel: modelFactory(configSchema),
})
})
}