diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..b762d8318
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "varfish/vueapp/ext/reev-frontend-lib"]
+ path = varfish/vueapp/ext/reev-frontend-lib
+ url = https://github.com/bihealth/reev-frontend-lib.git
diff --git a/cases/templates/cases/entrypoint.html b/cases/templates/cases/entrypoint.html
index 9449c2e14..06de5b276 100644
--- a/cases/templates/cases/entrypoint.html
+++ b/cases/templates/cases/entrypoint.html
@@ -12,6 +12,6 @@
- {% vite_scripts 'src/cases/main.js' %}
- {% vite_styles 'src/cases/main.js' %}
+ {% vite_scripts 'src/cases/main.ts' %}
+ {% vite_styles 'src/cases/main.ts' %}
{% endblock %}
diff --git a/cases/vueapp/src/main.ts b/cases/vueapp/src/main.ts
new file mode 100644
index 000000000..835f67695
--- /dev/null
+++ b/cases/vueapp/src/main.ts
@@ -0,0 +1,22 @@
+import App from '@cases/App.vue'
+import { createApp, nextTick } from 'vue'
+import { registerPlugins } from './plugins'
+
+declare global {
+ interface Window {
+ _paq: any[]
+ }
+}
+
+async function bootstrap() {
+ const app = createApp(App)
+
+ await registerPlugins(app)
+
+ app.mount('#app')
+
+ await nextTick()
+ window._paq?.push(['trackPageView'])
+}
+
+bootstrap()
diff --git a/cases/vueapp/src/plugins/index.ts b/cases/vueapp/src/plugins/index.ts
new file mode 100644
index 000000000..f682b6b79
--- /dev/null
+++ b/cases/vueapp/src/plugins/index.ts
@@ -0,0 +1,11 @@
+import type { App } from 'vue'
+
+import { router } from '../router'
+import { vuetify } from './vuetify'
+import { pinia } from '../stores'
+import { setupBackendUrls } from './reevFrontend'
+
+export async function registerPlugins(app: App) {
+ setupBackendUrls()
+ app.use(vuetify).use(router).use(pinia)
+}
diff --git a/cases/vueapp/src/plugins/reevFrontend.ts b/cases/vueapp/src/plugins/reevFrontend.ts
new file mode 100644
index 000000000..59ac72abb
--- /dev/null
+++ b/cases/vueapp/src/plugins/reevFrontend.ts
@@ -0,0 +1,14 @@
+import { urlConfig } from '@bihealth/reev-frontend-lib/lib/urlConfig'
+
+export function setupBackendUrls() {
+ urlConfig.baseUrlAnnonars = '/proxy/varfish/annonars'
+ urlConfig.baseUrlMehari = '/proxy/varfish/mehari'
+ urlConfig.baseUrlViguno = '/proxy/varfish/viguno'
+ urlConfig.baseUrlNginx = '/proxy/varfish/nginx'
+ urlConfig.baseUrlPubtator = '/proxy/remote/pubtator3-api'
+
+ // urlConfig.baseUrlCadaPrio = '/internal/proxy/cada-prio'
+ // urlConfig.baseUrlDotty = '/internal/proxy/dotty'
+ // urlConfig.baseUrlVariantValidator = '/remote/variantvalidator'
+ // urlConfig.baseUrlPubtator = '/remote/pubtator3-api'
+}
diff --git a/cases/vueapp/src/plugins/vuetify.ts b/cases/vueapp/src/plugins/vuetify.ts
new file mode 100644
index 000000000..8ea383055
--- /dev/null
+++ b/cases/vueapp/src/plugins/vuetify.ts
@@ -0,0 +1,61 @@
+/**
+ * plugins/vuetify.ts
+ *
+ * Framework documentation: https://vuetifyjs.com`
+ */
+// Styles
+import '@mdi/font/css/materialdesignicons.css'
+// Composables
+import { type ThemeDefinition, createVuetify } from 'vuetify'
+import { aliases, mdi } from 'vuetify/iconsets/mdi'
+import { md3 } from 'vuetify/blueprints'
+import * as components from 'vuetify/components'
+import * as directives from 'vuetify/directives'
+import '../styles/main.scss'
+
+const customLightTheme: ThemeDefinition = {
+ dark: false,
+ colors: {
+ primary: '#757ce8',
+ secondary: '#3f50b5',
+ tertiary: '#002884',
+ background: '#eeeeee',
+ success: '#4caf50',
+ warning: '#ff9800',
+ error: '#f44336',
+ info: '#f0f2f5',
+ },
+}
+
+// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
+export const vuetify = createVuetify({
+ blueprint: md3,
+ components: {
+ ...components,
+ },
+ icons: {
+ defaultSet: 'mdi',
+ aliases,
+ sets: {
+ mdi,
+ },
+ },
+ directives,
+ defaults: {
+ global: {
+ flat: true,
+ },
+ VCard: {
+ rounded: 'lg',
+ },
+ VSheet: {
+ rounded: 'lg',
+ },
+ },
+ theme: {
+ defaultTheme: 'customLightTheme',
+ themes: {
+ customLightTheme,
+ },
+ },
+})
diff --git a/cases/vueapp/src/main.js b/cases/vueapp/src/router/index.ts
similarity index 93%
rename from cases/vueapp/src/main.js
rename to cases/vueapp/src/router/index.ts
index 96352d3b6..211dae3f8 100644
--- a/cases/vueapp/src/main.js
+++ b/cases/vueapp/src/router/index.ts
@@ -1,4 +1,3 @@
-import App from '@cases/App.vue'
import CaseDetailApp from '@cases/components/CaseDetailApp.vue'
import CaseListApp from '@cases/components/CaseListApp.vue'
import SvDetails from '@svs/components/SvDetails.vue'
@@ -6,8 +5,6 @@ import SvFilterApp from '@svs/components/SvFilterApp.vue'
import { useHistoryStore } from '@varfish/stores/history'
import FilterApp from '@variants/components/FilterApp.vue'
import VariantDetails from '@variants/components/VariantDetails.vue'
-import { createPinia } from 'pinia'
-import { createApp } from 'vue'
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
@@ -117,7 +114,7 @@ const routes = [
},
]
-const router = createRouter({
+export const router = createRouter({
history: createWebHashHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
@@ -134,12 +131,6 @@ const router = createRouter({
},
})
-const pinia = createPinia()
-const app = createApp(App)
-app.use(router)
-app.use(pinia)
-app.mount('#app')
-
router.beforeEach((_to, from) => {
// Push history element, initial will be swallowed by store.
const historyStore = useHistoryStore()
diff --git a/cases/vueapp/src/stores/index.ts b/cases/vueapp/src/stores/index.ts
new file mode 100644
index 000000000..72afdebc9
--- /dev/null
+++ b/cases/vueapp/src/stores/index.ts
@@ -0,0 +1,4 @@
+// Utilities
+import { createPinia } from 'pinia'
+
+export const pinia = createPinia()
diff --git a/cases/vueapp/src/styles/main.scss b/cases/vueapp/src/styles/main.scss
new file mode 100644
index 000000000..8110ca3be
--- /dev/null
+++ b/cases/vueapp/src/styles/main.scss
@@ -0,0 +1,22 @@
+@use 'vuetify' with (
+ $utilities: (
+ margin: false,
+ margin-x: false,
+ margin-y: false,
+ margin-top: false,
+ margin-bottom: false,
+ margin-left: false,
+ margin-right: false,
+ margin-start: false,
+ margin-end: false,
+ negative-margin: false,
+ negative-margin-x: false,
+ negative-margin-y: false,
+ negative-margin-top: false,
+ negative-margin-bottom: false,
+ negative-margin-left: false,
+ negative-margin-right: false,
+ negative-margin-start: false,
+ negative-margin-end: false,
+ )
+);
diff --git a/config/urls.py b/config/urls.py
index 89b5c96c2..6fe0711ec 100644
--- a/config/urls.py
+++ b/config/urls.py
@@ -121,6 +121,14 @@ def handler500(request, *args, **argv):
ignored_request_headers=HttpProxy.ignored_upstream_headers + ["cookie"],
),
),
+ # Augment url patterns with proxy for PubTator3
+ url(
+ r"^proxy/remote/pubtator3-api/(?P.*)$",
+ HttpProxy.as_view(
+ base_url="https://www.ncbi.nlm.nih.gov/research/pubtator3-api/",
+ ignored_request_headers=HttpProxy.ignored_upstream_headers + ["cookie"],
+ ),
+ ),
url(
r"^proxy/varfish/viguno/(?P.*)$",
HttpProxy.as_view(
diff --git a/materialdesignicons-webfont.woff2 b/materialdesignicons-webfont.woff2
new file mode 100644
index 000000000..8c69b85f6
Binary files /dev/null and b/materialdesignicons-webfont.woff2 differ
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 000000000..db171856f
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "./varfish/vueapp/tsconfig.json"
+}
diff --git a/varfish/vueapp/ext/reev-frontend-lib b/varfish/vueapp/ext/reev-frontend-lib
new file mode 160000
index 000000000..0a9899742
--- /dev/null
+++ b/varfish/vueapp/ext/reev-frontend-lib
@@ -0,0 +1 @@
+Subproject commit 0a9899742e21cca45565107f3937593f34aaea92
diff --git a/varfish/vueapp/jsconfig.json b/varfish/vueapp/jsconfig.json
index 4c0d8ff4a..c5d59ce29 100644
--- a/varfish/vueapp/jsconfig.json
+++ b/varfish/vueapp/jsconfig.json
@@ -10,7 +10,8 @@
"@svs/*": ["./src/svs/*"],
"@cases/*": ["./src/cases/*"],
"@cases_qc/*": ["./src/cases_qc/*"],
- "@cohorts/*": ["./src/cohorts/*"]
+ "@cohorts/*": ["./src/cohorts/*"],
+ "@bihealth/reev-frontend-lib/*": ["./src/reev-frontend-lib/src/*"]
}
}
}
diff --git a/varfish/vueapp/package-lock.json b/varfish/vueapp/package-lock.json
index 86ea16c46..168268b91 100644
--- a/varfish/vueapp/package-lock.json
+++ b/varfish/vueapp/package-lock.json
@@ -8,20 +8,26 @@
"name": "varfish-server",
"version": "2.0.0",
"dependencies": {
+ "@mdi/font": "^7.4.47",
+ "@protobuf-ts/runtime": "^2.9.3",
"@reactgular/chunks": "^1.0.1",
+ "@types/luxon": "^3.4.2",
"@vueform/multiselect": "^2.6.2",
"@vuelidate/core": "^2.0.3",
"@vuelidate/validators": "^2.0.4",
"ag-grid-vue3": "^30.1.0",
"camelcase": "^8.0.0",
"core-js": "^3.32.2",
+ "fast-deep-equal": "^3.1.3",
"igv": "^2.15.11",
"javascript-time-ago": "^2.5.9",
"lodash.debounce": "^4.0.8",
"lodash.isequal": "^4.5.0",
+ "luxon": "^3.4.4",
"pinia": "^2.1.6",
"snakecase": "^1.0.0",
"sort-by-typescript": "^1.2.5",
+ "title-case": "^4.3.1",
"vega": "^5.25.0",
"vega-embed": "^6.22.2",
"vega-lite": "^5.15.0",
@@ -29,6 +35,7 @@
"vue-draggable-next": "^2.2.1",
"vue-router": "^4.2.5",
"vue3-easy-data-table": "^1.5.47",
+ "vuetify": "^3.5.3",
"yarn": "^1.22.19"
},
"devDependencies": {
@@ -81,8 +88,10 @@
"prettier": "3.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "sass": "^1.70.0",
"storybook": "^7.6.10",
"storybook-addon-fetch-mock": "^1.0.1",
+ "unplugin-fonts": "^1.1.1",
"unplugin-icons": "^0.18.3",
"unplugin-vue-components": "^0.26.0",
"vite": "^4.5.2",
@@ -3314,6 +3323,11 @@
"integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==",
"dev": true
},
+ "node_modules/@mdi/font": {
+ "version": "7.4.47",
+ "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz",
+ "integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw=="
+ },
"node_modules/@mdx-js/react": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-2.3.0.tgz",
@@ -3748,6 +3762,11 @@
"url": "https://opencollective.com/popperjs"
}
},
+ "node_modules/@protobuf-ts/runtime": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime/-/runtime-2.9.3.tgz",
+ "integrity": "sha512-nivzCpg/qYD0RX2OmHOahJALb8ndjGmUhNBcTJ0BbXoqKwCSM6vYA+vegzS3rhuaPgbyC7Ec8idlnizzUfIRuw=="
+ },
"node_modules/@radix-ui/number": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz",
@@ -6906,6 +6925,11 @@
"integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==",
"dev": true
},
+ "node_modules/@types/luxon": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.2.tgz",
+ "integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA=="
+ },
"node_modules/@types/mdx": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.7.tgz",
@@ -12056,8 +12080,7 @@
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-diff": {
"version": "1.3.0",
@@ -13347,6 +13370,12 @@
"resolved": "https://registry.npmjs.org/igv/-/igv-2.15.11.tgz",
"integrity": "sha512-oJs6z4ogv1GefIWaMdG5s4jFRuFQ/PjUgrGBMn12SbeeIC/VgHkHr56K5yIaC8ZSyameq/7IFDQaXu0qIu6cpA=="
},
+ "node_modules/immutable": {
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
+ "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==",
+ "dev": true
+ },
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -15173,6 +15202,14 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/luxon": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz",
+ "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/lz-string": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
@@ -19254,6 +19291,23 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
+ "node_modules/sass": {
+ "version": "1.70.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz",
+ "integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@@ -20610,6 +20664,11 @@
"node": ">=14.0.0"
}
},
+ "node_modules/title-case": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/title-case/-/title-case-4.3.1.tgz",
+ "integrity": "sha512-VnPxQ+/j0X2FZ4ceGq1oLruTLjtN5Ul4sam5ypd4mDZLm1eHwkwip1gLxqhON/j4qyTlUlfPKslE/t4NPSlxhg=="
+ },
"node_modules/titleize": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
@@ -21101,6 +21160,25 @@
"webpack-virtual-modules": "^0.6.1"
}
},
+ "node_modules/unplugin-fonts": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/unplugin-fonts/-/unplugin-fonts-1.1.1.tgz",
+ "integrity": "sha512-/Aw/rL9D2aslGGM0vi+2R2aG508RSwawLnnBuo+JDSqYc4cHJO1R1phllhN6GysEhBp/6a4B6+vSFPVapWyAAw==",
+ "dev": true,
+ "dependencies": {
+ "fast-glob": "^3.2.12",
+ "unplugin": "^1.3.1"
+ },
+ "peerDependencies": {
+ "@nuxt/kit": "^3.0.0",
+ "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@nuxt/kit": {
+ "optional": true
+ }
+ }
+ },
"node_modules/unplugin-icons": {
"version": "0.18.3",
"resolved": "https://registry.npmjs.org/unplugin-icons/-/unplugin-icons-0.18.3.tgz",
@@ -21560,7 +21638,6 @@
}
},
"node_modules/vega-embed/node_modules/yallist": {
- "version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"inBundle": true
@@ -22411,6 +22488,39 @@
"vue": "^3.2.45"
}
},
+ "node_modules/vuetify": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.5.3.tgz",
+ "integrity": "sha512-z2H1HYEfFeqHTp47VbFOLAv6Nard/eP4+qIXY9c6Z/uUflLhq5K8cyXL6MKhfIzyUsto+KszjVTyX+bu7zT2QA==",
+ "engines": {
+ "node": "^12.20 || >=14.13"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/johnleider"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.7",
+ "vite-plugin-vuetify": ">=1.0.0-alpha.12",
+ "vue": "^3.3.0",
+ "vue-i18n": "^9.0.0",
+ "webpack-plugin-vuetify": ">=2.0.0-alpha.11"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ },
+ "vite-plugin-vuetify": {
+ "optional": true
+ },
+ "vue-i18n": {
+ "optional": true
+ },
+ "webpack-plugin-vuetify": {
+ "optional": true
+ }
+ }
+ },
"node_modules/walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
diff --git a/varfish/vueapp/package.json b/varfish/vueapp/package.json
index d09f1a693..0bfc4b0c9 100644
--- a/varfish/vueapp/package.json
+++ b/varfish/vueapp/package.json
@@ -14,20 +14,26 @@
"build-storybook": "storybook build"
},
"dependencies": {
+ "@mdi/font": "^7.4.47",
+ "@protobuf-ts/runtime": "^2.9.3",
"@reactgular/chunks": "^1.0.1",
+ "@types/luxon": "^3.4.2",
"@vueform/multiselect": "^2.6.2",
"@vuelidate/core": "^2.0.3",
"@vuelidate/validators": "^2.0.4",
"ag-grid-vue3": "^30.1.0",
"camelcase": "^8.0.0",
"core-js": "^3.32.2",
+ "fast-deep-equal": "^3.1.3",
"igv": "^2.15.11",
"javascript-time-ago": "^2.5.9",
"lodash.debounce": "^4.0.8",
"lodash.isequal": "^4.5.0",
+ "luxon": "^3.4.4",
"pinia": "^2.1.6",
"snakecase": "^1.0.0",
"sort-by-typescript": "^1.2.5",
+ "title-case": "^4.3.1",
"vega": "^5.25.0",
"vega-embed": "^6.22.2",
"vega-lite": "^5.15.0",
@@ -35,6 +41,7 @@
"vue-draggable-next": "^2.2.1",
"vue-router": "^4.2.5",
"vue3-easy-data-table": "^1.5.47",
+ "vuetify": "^3.5.3",
"yarn": "^1.22.19"
},
"devDependencies": {
@@ -87,8 +94,10 @@
"prettier": "3.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "sass": "^1.70.0",
"storybook": "^7.6.10",
"storybook-addon-fetch-mock": "^1.0.1",
+ "unplugin-fonts": "^1.1.1",
"unplugin-icons": "^0.18.3",
"unplugin-vue-components": "^0.26.0",
"vite": "^4.5.2",
diff --git a/varfish/vueapp/tsconfig.json b/varfish/vueapp/tsconfig.json
index 1fe264707..6c4df1792 100644
--- a/varfish/vueapp/tsconfig.json
+++ b/varfish/vueapp/tsconfig.json
@@ -11,7 +11,8 @@
"@svs/*": ["./src/svs/*"],
"@cases/*": ["./src/cases/*"],
"@cases_qc/*": ["./src/cases_qc/*"],
- "@cohorts/*": ["./src/cohorts/*"]
+ "@cohorts/*": ["./src/cohorts/*"],
+ "@bihealth/reev-frontend-lib/*": ["./ext/reev-frontend-lib/src/*"]
}
}
}
diff --git a/varfish/vueapp/vite.config.js b/varfish/vueapp/vite.config.js
index dcfbffa79..f85345e5e 100644
--- a/varfish/vueapp/vite.config.js
+++ b/varfish/vueapp/vite.config.js
@@ -2,6 +2,7 @@ const { resolve } = require('path')
import Vue from '@vitejs/plugin-vue'
import IconsResolver from 'unplugin-icons/resolver'
import Icons from 'unplugin-icons/vite'
+import Unfonts from 'unplugin-fonts/vite'
import Components from 'unplugin-vue-components/vite'
import { defineConfig } from 'vite'
@@ -30,12 +31,23 @@ export default defineConfig({
plugins: [
Vue(),
Components({
- resolvers: [IconsResolver()],
+ dts: true,
+ resolvers: [IconsResolver({ enabledCollections: ['mdi'],})],
}),
Icons({
- autoInstall: true,
+ // autoInstall: true,
compiler: 'vue3',
}),
+ Unfonts({
+ google: {
+ families: [
+ {
+ name: 'Roboto',
+ styles: 'wght@100;300;400;500;700;900'
+ }
+ ]
+ }
+ })
],
resolve: {
alias: {
@@ -47,9 +59,13 @@ export default defineConfig({
'@cases': resolve(__dirname, './src/cases'),
'@cases_qc': resolve(__dirname, './src/cases_qc'),
'@cohorts': resolve(__dirname, './src/cohorts'),
+ '@bihealth/reev-frontend-lib': resolve(__dirname, './ext/reev-frontend-lib/src'),
},
preserveSymlinks: true,
},
+ server: {
+ origin: "http://127.0.0.1:3000"
+ },
test: {
coverage: {
all: true,
diff --git a/variants/vueapp/src/components/VariantDetails.vue b/variants/vueapp/src/components/VariantDetails.vue
index 2c672ac9b..5fc56149c 100644
--- a/variants/vueapp/src/components/VariantDetails.vue
+++ b/variants/vueapp/src/components/VariantDetails.vue
@@ -10,8 +10,12 @@
* See `SvDetails` for a peer app for structural variants
*/
-import { computed, onMounted } from 'vue'
+import { computed, defineAsyncComponent, onMounted } from 'vue'
import { useRouter } from 'vue-router'
+import { StoreState } from '@bihealth/reev-frontend-lib/stores'
+import { useGeneInfoStore } from '@bihealth/reev-frontend-lib/stores/geneInfo'
+import { useSeqvarInfoStore } from '@bihealth/reev-frontend-lib/stores/seqvarInfo'
+import { Seqvar, SeqvarImpl } from '@bihealth/reev-frontend-lib/lib/genomicVars'
import { useCaseDetailsStore } from '@cases/stores/caseDetails'
import { useVariantDetailsStore } from '@variants/stores/variantDetails'
import { useVariantQueryStore } from '@variants/stores/variantQuery'
@@ -41,6 +45,14 @@ import Overlay from '@varfish/components/Overlay.vue'
import { allNavItems } from '@variants/components/VariantDetails.fields'
import { watch } from 'vue'
+const GeneOverviewCard = defineAsyncComponent(
+ () =>
+ import(
+ '@bihealth/reev-frontend-lib/components/GeneOverviewCard/GeneOverviewCard.vue'
+ ),
+)
+
+/** This component's props. */
const props = defineProps<{
/** UUID of the result row to display. */
resultRowUuid?: string
@@ -60,6 +72,11 @@ const router = useRouter()
// Store-related
+/** Information about the sequence variant, used to fetch information on load. */
+const seqvarInfoStore = useSeqvarInfoStore()
+/** Information about the affected gene, used to fetch information on load. */
+const geneInfoStore = useGeneInfoStore()
+
const historyStore = useHistoryStore()
const caseDetailsStore = useCaseDetailsStore()
@@ -125,6 +142,10 @@ const refreshStores = async () => {
if (props.resultRowUuid && props.selectedSection) {
await variantResultSetStore.initialize(appContext.csrf_token)
await variantResultSetStore.fetchResultSetViaRow(props.resultRowUuid)
+ console.log(
+ 'variantResultSetStore.resultRow',
+ variantResultSetStore.resultRow,
+ )
await Promise.all([
variantFlagsStore.initialize(
appContext.csrf_token,
@@ -147,7 +168,29 @@ const refreshStores = async () => {
variantResultSetStore.caseUuid,
),
])
- variantDetailsStore.fetchVariantDetails(variantResultSetStore.resultRow)
+ await variantDetailsStore.fetchVariantDetails(
+ variantResultSetStore.resultRow,
+ )
+
+ // TODO: properly use types
+ if (variantResultSetStore.resultRow !== undefined) {
+ const seqvar: Seqvar = new SeqvarImpl(
+ variantResultSetStore.resultRow.release === 'GRCh37'
+ ? 'grch37'
+ : 'grch38',
+ variantResultSetStore.resultRow.chromosome,
+ variantResultSetStore.resultRow.start,
+ variantResultSetStore.resultRow.reference,
+ variantResultSetStore.resultRow.alternative,
+ )
+ await Promise.all([
+ seqvarInfoStore.initialize(seqvar),
+ geneInfoStore.initialize(
+ variantResultSetStore.resultRow.payload!.hgnc_id,
+ seqvar.genomeBuild,
+ ),
+ ])
+ }
}
document.querySelector(`#${props.selectedSection}`)?.scrollIntoView()
@@ -170,6 +213,11 @@ onMounted(() => {
+
+
+
+
+