@molgenis/vip-report-template 6.0.2 → 6.1.1

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/.husky/pre-commit CHANGED
@@ -1,4 +1 @@
1
- #!/bin/sh
2
- . "$(dirname "$0")/_/husky.sh"
3
-
4
1
  npx lint-staged
package/.travis.yml CHANGED
@@ -27,11 +27,14 @@ deploy:
27
27
  secure: TxQUU8xNTVTqhQ6pYTR+ic7Crv6rPZ7UbRo8HJJOGlFA30Vb/O36kh3Vgwx3fM5oinC1I38pzmHjJ4WVz2qiUZcgNzDHMorQhErbfSWLO8G7XTsVkMkyozPPtgdCCT2Z7FfdTKmY5an+V4ZJlreM83+vlJmUzMoGahZElESBk94QkTnPAqk46whXAf/zToEw7OJsxd2N3uPyPB8+rgg5VMApRBsCegt3KyetiMBIYWX+kJLxXEGK7OnJmxz1SGrYHR87YEDog7awBIhrXNcBWc4Lj55oWEqp3JQlpLnVDhEUCSO8cmQkyIMTYZ3eIKoyrDk9vfAYYbDsRvagFXKTZGvv0ZQv8s7a1lWAadTyvgbmo3cvX/KHfam5pGf2DFEXWIHZgvoIzq8GY6V4sjOEWRG2sAn+jKiNT5jPgG8sG0faP2JVr55WoN4jRthk5ABckyS8PByWrwcLILTeBPuX7DpiKtzUzzRw/qHAGo59+bFyZiKIc5I+S59fnttJ6Vz4jpjsavOzNsgIGUsTs3y1kosNLYoJVcI3RjpgHQuOfzawKb2l22B5wbJ1/1llhrSqYCtEjAhUuruB3bhy+/WiN4ulKp29Ct7/IEN3ctBXdMBm2xCPlsPSTBeXzwJNeWykTnpFx9qykjtSj3CwS8ZDnY3M+/dLhywrI46EGa03YRw=
28
28
  on:
29
29
  tags: true
30
- edge: true
30
+ edge:
31
+ branch: v2.0.3-beta.4 # workaround for https://travis-ci.community/t/builds-suddenly-fail-with-error-installing-dpl/14270/3
31
32
  - provider: releases
32
33
  token:
33
34
  secure: rQ19Q5xN6T+dJp4nDT+B4QREJNCc9HpOdipE7jcAP/PVD49kd3AI4joZD9nBn53a091rl7VHviqzyRvHyvBI00VWGhQOmbUqd45c5h4Vn0qUZno2Wl2M7iuUyllvovQHS0C34nLDSBkKhJv0ESit/xiyyVy8JxwO1mgFcLgsY0cKiupwbhepUw5V2S458pNLW9e4RxT7RIaQWUagYp+PJYRKAYn5AAxih65mv2+wSGQPzcOKJDRSTlDtLaCrfZCNJm/7f3iSAOm1CCA1HLxNO2ACFL4bhnghWPS7O6VyTv1POexgwbH0OQxHmO/pdm3geLrTWX7PaHaZNUB1CHoNXC5FE/J9sUSrjClfGL9qFo5WEkBAgH3a5lLwUoCWZecUJPnyeIEFieg5OSjnXFrTECWo5Ut4g5RtzOWQtTLEwOXQgDBtE3NLkH/DRayO9vliEs9/6CnZ8AndH17cj/GmB//2DTjOMr3yCQVuI5ZeANBAUoXAg/C6kQDTdP8oyLay7UBJnX1aEWWLf3Gwo0UBFE83YIuzqVzIvU8HYgFiPgjxFwKBmebS4qu1n9ils2X0nWaY9KZY4lIjzkxsgsZ2pqt1Z6a5AQsEqXv06Tjy6tB7/I9TG7vl4eTBBJBPsRKMNnTfkE6Zr3oHC+ihWIMolAqyaTriOh23Gs/xzEuK+T8=
34
35
  file: dist/vip-report-template.html
35
36
  on:
36
37
  tags: true
37
- edge: true # opt in to dpl v2
38
+ edge:
39
+ branch: v2.0.3-beta.4 # workaround for https://travis-ci.community/t/builds-suddenly-fail-with-error-installing-dpl/14270/3
40
+
package/index.html CHANGED
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html lang="en">
2
+ <html lang="en" data-theme="light">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molgenis/vip-report-template",
3
- "version": "6.0.2",
3
+ "version": "6.1.1",
4
4
  "description": "Report Template for Variant Call Format (VCF) Report Generator",
5
5
  "scripts": {
6
6
  "build": "vite build",
@@ -9,39 +9,39 @@
9
9
  "dev": "vite",
10
10
  "format": "prettier --write src/**/*.{tsx,ts}",
11
11
  "lint": "eslint src/**/*.{tsx,ts}",
12
- "prepare": "husky install",
12
+ "prepare": "husky",
13
13
  "test": "vitest run",
14
14
  "test:watch": "vitest"
15
15
  },
16
16
  "license": "LGPL-3.0",
17
17
  "devDependencies": {
18
- "@molgenis/vite-plugin-inline": "^1.0.21",
19
- "@typescript-eslint/eslint-plugin": "^6.19.1",
20
- "@typescript-eslint/parser": "^6.19.1",
21
- "@vitest/coverage-v8": "^1.2.1",
22
- "bulma": "^0.9.4",
23
- "eslint": "^8.56.0",
18
+ "@molgenis/vite-plugin-inline": "^1.0.24",
19
+ "@typescript-eslint/eslint-plugin": "^7.12.0",
20
+ "@typescript-eslint/parser": "^7.12.0",
21
+ "@vitest/coverage-v8": "^1.6.0",
22
+ "bulma": "^1.0.1",
23
+ "eslint": "^8.57.0",
24
24
  "eslint-config-prettier": "^9.1.0",
25
25
  "eslint-plugin-prettier": "^5.1.3",
26
- "eslint-plugin-solid": "^0.13.1",
27
- "husky": "^9.0.5",
28
- "jsdom": "^24.0.0",
29
- "prettier": "^3.2.4",
30
- "sass": "^1.70.0",
31
- "typescript": "^5.3.3",
32
- "vite": "^5.0.12",
33
- "vite-plugin-solid": "^2.9.1",
34
- "vitest": "^1.2.1"
26
+ "eslint-plugin-solid": "^0.14.0",
27
+ "husky": "^9.0.11",
28
+ "jsdom": "^24.1.0",
29
+ "prettier": "^3.3.1",
30
+ "sass": "^1.77.4",
31
+ "typescript": "^5.4.5",
32
+ "vite": "^5.2.12",
33
+ "vite-plugin-solid": "^2.10.2",
34
+ "vitest": "^1.6.0"
35
35
  },
36
36
  "dependencies": {
37
- "@fortawesome/fontawesome-svg-core": "^6.5.1",
38
- "@fortawesome/free-solid-svg-icons": "^6.5.1",
39
- "@molgenis/vip-report-api": "^5.0.2",
40
- "@molgenis/vip-report-vcf": "^2.0.0",
41
- "@solidjs/router": "^0.9.1",
37
+ "@fortawesome/fontawesome-svg-core": "^6.5.2",
38
+ "@fortawesome/free-solid-svg-icons": "^6.5.2",
39
+ "@molgenis/vip-report-api": "^5.0.4",
40
+ "@molgenis/vip-report-vcf": "^2.0.2",
41
+ "@solidjs/router": "^0.13.5",
42
42
  "base64-js": "^1.5.1",
43
43
  "igv": "^2.15.11",
44
- "solid-js": "^1.8.12"
44
+ "solid-js": "^1.8.17"
45
45
  },
46
46
  "lint-staged": {
47
47
  "src/**/*.{tsx,ts}": [
package/src/App.tsx CHANGED
@@ -1,25 +1,9 @@
1
- import { Component, ErrorBoundary, onMount } from "solid-js";
2
- import { Link, Route, Routes, useLocation, useNavigate } from "@solidjs/router";
3
- import { VariantsView } from "./views/Variants";
4
- import { Variant } from "./views/Variant";
5
- import VariantData from "./views/data/VariantData";
6
- import { Samples } from "./views/Samples";
7
- import SampleData from "./views/data/SampleData";
8
- import { Sample } from "./views/Sample";
9
- import { VariantConsequence } from "./views/VariantConsequence";
10
- import { SampleVariantConsequenceView } from "./views/SampleVariantConsequence";
11
- import { SampleVariantsView } from "./views/SampleVariants";
12
- import { Error } from "./components/Error";
13
- import SampleVariantData from "./views/data/SampleVariantData";
14
- import { SampleVariantView } from "./views/SampleVariant";
15
- import { Home } from "./views/Home";
1
+ import { onMount, ParentComponent } from "solid-js";
2
+ import { useLocation, useNavigate } from "@solidjs/router";
16
3
  import api from "./Api";
17
4
  import { DatasetDropdown } from "./components/DatasetDropdown";
18
- import SampleVariantConsequenceData from "./views/data/SampleVariantConsequenceData";
19
- import VariantConsequenceData from "./views/data/VariantConsequenceData";
20
- import { Help } from "./views/Help";
21
5
 
22
- const App: Component = () => {
6
+ const App: ParentComponent = (props) => {
23
7
  const navigate = useNavigate();
24
8
  const location = useLocation();
25
9
 
@@ -44,23 +28,23 @@ const App: Component = () => {
44
28
  <>
45
29
  <nav class="navbar is-fixed-top is-light" role="navigation" aria-label="main navigation">
46
30
  <div class="navbar-brand">
47
- <Link class="navbar-item has-text-weight-semibold" href="/">
31
+ <a class="navbar-item has-text-weight-semibold" href="/">
48
32
  Variant Interpretation Pipeline
49
- </Link>
33
+ </a>
50
34
  </div>
51
35
  <div class="navbar-menu">
52
36
  <div class="navbar-item has-dropdown is-hoverable">
53
- <Link class="navbar-link" href="/">
37
+ <a class="navbar-link" href="/">
54
38
  Report
55
- </Link>
39
+ </a>
56
40
  <div class="navbar-dropdown">
57
- <Link class="navbar-item" href="/samples">
41
+ <a class="navbar-item" href="/samples">
58
42
  Samples
59
- </Link>
43
+ </a>
60
44
  <hr class="navbar-divider" />
61
- <Link class="navbar-item" href="/variants">
45
+ <a class="navbar-item" href="/variants">
62
46
  Variants
63
- </Link>
47
+ </a>
64
48
  </div>
65
49
  </div>
66
50
  {api.isDatasetSupport() && (
@@ -69,48 +53,13 @@ const App: Component = () => {
69
53
  </div>
70
54
  )}
71
55
  <div class="navbar-end">
72
- <Link class="navbar-item" href="/help">
56
+ <a class="navbar-item" href="/help">
73
57
  Help
74
- </Link>
58
+ </a>
75
59
  </div>
76
60
  </div>
77
61
  </nav>
78
- <div class="container is-fluid">
79
- <ErrorBoundary fallback={(err) => <Error error={err as unknown} />}>
80
- <Routes>
81
- <Route path="/" element={<Home />} />
82
- <Route path="/samples">
83
- <Route path="/" element={<Samples />} />
84
- <Route path="/:sampleId" data={SampleData}>
85
- <Route path="/" element={<Sample />} />
86
- <Route path="/variants">
87
- <Route path="/" element={<SampleVariantsView />} />
88
- <Route path="/:variantId" data={SampleVariantData}>
89
- <Route path="/" element={<SampleVariantView />} />
90
- <Route path="/consequences">
91
- <Route
92
- path="/:consequenceId"
93
- element={<SampleVariantConsequenceView />}
94
- data={SampleVariantConsequenceData}
95
- />
96
- </Route>
97
- </Route>
98
- </Route>
99
- </Route>
100
- </Route>
101
- <Route path="/variants">
102
- <Route path="/" element={<VariantsView />} />
103
- <Route path="/:variantId" data={VariantData}>
104
- <Route path="/" element={<Variant />} />
105
- <Route path="/consequences">
106
- <Route path="/:consequenceId" element={<VariantConsequence />} data={VariantConsequenceData} />
107
- </Route>
108
- </Route>
109
- </Route>
110
- <Route path="/help" element={<Help />} />
111
- </Routes>
112
- </ErrorBoundary>
113
- </div>
62
+ <div class="container is-fluid">{props.children}</div>
114
63
  </>
115
64
  );
116
65
  };
@@ -1,50 +1,9 @@
1
1
  @charset "utf-8";
2
- $gap: 8px;
3
-
4
- $notification-padding: 0.75rem 0.75rem 0.75rem 0.75rem;
5
- $notification-padding-ltr: 0.75rem 0.75rem 0.75rem 0.75rem;
6
- $notification-padding-rtl: 0.75rem 0.75rem 0.75rem 0.75rem;
7
-
8
- @import "bulma/sass/utilities/initial-variables";
9
- @import "bulma/sass/utilities/functions";
10
- @import "bulma/sass/utilities/derived-variables";
11
- @import "bulma/sass/utilities/mixins";
12
- @import "bulma/sass/utilities/controls";
13
- @import "bulma/sass/utilities/extends";
14
-
15
- @import "bulma/sass/base/minireset";
16
- @import "bulma/sass/base/generic";
17
- @import "bulma/sass/base/animations";
18
-
19
- @import "bulma/sass/elements/button";
20
- @import "bulma/sass/elements/container";
21
- @import "bulma/sass/elements/icon";
22
- @import "bulma/sass/elements/notification";
23
- @import "bulma/sass/elements/table";
24
- @import "bulma/sass/elements/title";
25
-
26
- @import "bulma/sass/form/shared";
27
- @import "bulma/sass/form/input-textarea";
28
- @import "bulma/sass/form/checkbox-radio";
29
- @import "bulma/sass/form/select";
30
- @import "bulma/sass/form/tools";
31
-
32
- @import "bulma/sass/grid/columns";
33
-
34
- @import "bulma/sass/components/breadcrumb";
35
- @import "bulma/sass/components/card";
36
- @import "bulma/sass/components/navbar";
37
- @import "bulma/sass/components/pagination";
38
-
39
- @import "bulma/sass/helpers/color";
40
- @import "bulma/sass/helpers/flexbox";
41
- @import "bulma/sass/helpers/float";
42
- @import "bulma/sass/helpers/other";
43
- @import "bulma/sass/helpers/overflow";
44
- @import "bulma/sass/helpers/position";
45
- @import "bulma/sass/helpers/spacing";
46
- @import "bulma/sass/helpers/typography";
47
- @import "bulma/sass/helpers/visibility";
2
+
3
+ @use "bulma/sass" with(
4
+ $gap: 8px,
5
+ $notification-padding: 0.75rem 0.75rem,
6
+ );
48
7
 
49
8
  html {
50
9
  font-size: 13px;
@@ -92,7 +51,7 @@ td {
92
51
  }
93
52
 
94
53
  .pagination-ellipsis {
95
- min-width: $pagination-min-width;
54
+ min-width: 2.5em;
96
55
  }
97
56
 
98
57
  .container {
@@ -120,4 +79,10 @@ table.is-borderless td,
120
79
 
121
80
  .inline-control-text {
122
81
  line-height: 32.5px
82
+ }
83
+
84
+ .scrolling-div {
85
+ margin-top: 8px;
86
+ overflow-y: auto;
87
+ max-height: calc(100vh - 78px) !important;
123
88
  }
@@ -1,4 +1,3 @@
1
- import { Link } from "@solidjs/router";
2
1
  import { Component, For } from "solid-js";
3
2
 
4
3
  export type BreadCrumbItem = { href?: string; text: string };
@@ -12,17 +11,17 @@ export const Breadcrumb: Component<{
12
11
  <nav class="breadcrumb has-succeeds-separator">
13
12
  <ul>
14
13
  <li classList={{ "is-active": props.items.length === 0 }}>
15
- <Link href="/">
14
+ <a href="/">
16
15
  <span class="icon is-small mr-2">
17
16
  <i class="fas fa-home" />
18
17
  </span>
19
18
  <span>Report</span>
20
- </Link>
19
+ </a>
21
20
  </li>
22
21
  <For each={props.items}>
23
22
  {(link, i) => (
24
23
  <li classList={{ "is-active": i() === props.items.length - 1 }}>
25
- <Link href={link.href || "#"}>{link.text}</Link>
24
+ <a href={link.href || "#"}>{link.text}</a>
26
25
  </li>
27
26
  )}
28
27
  </For>
@@ -6,7 +6,7 @@ import { ValueArray } from "@molgenis/vip-report-vcf/src/ValueParser";
6
6
  import { Info } from "./record/Info";
7
7
  import { FieldValue } from "./record/field/Field";
8
8
  import { isCsqInfo } from "../utils/csqUtils";
9
- import { Link, useLocation } from "@solidjs/router";
9
+ import { useLocation } from "@solidjs/router";
10
10
 
11
11
  export const InfoCollapsablePane: Component<{
12
12
  fields: FieldMetadata[];
@@ -58,8 +58,8 @@ export const InfoCollapsablePane: Component<{
58
58
  <>
59
59
  {j() != 0 && collapsed() && <br />}
60
60
  {(j() == 0 || collapsed()) &&
61
- (isCsqInfo(field, "Consequence") ? (
62
- <Link href={`${useLocation().pathname}/${props.record.id}/consequences/${j()}`}>
61
+ (isCsqInfo(field, "VIPC") ? (
62
+ <a href={`${useLocation().pathname}/${props.record.id}/consequences/${j()}`}>
63
63
  <Info
64
64
  info={value}
65
65
  infoMeta={field}
@@ -68,7 +68,7 @@ export const InfoCollapsablePane: Component<{
68
68
  isPossibleCompound: props.isPossibleCompound,
69
69
  }}
70
70
  />
71
- </Link>
71
+ </a>
72
72
  ) : (
73
73
  <Info
74
74
  info={value}
@@ -1,4 +1,4 @@
1
- import { Link, useNavigate } from "@solidjs/router";
1
+ import { useNavigate } from "@solidjs/router";
2
2
  import { Component, createMemo, For, Show } from "solid-js";
3
3
  import { Item, Phenotype, PhenotypicFeature, Sample } from "@molgenis/vip-report-api/src/Api";
4
4
  import { HpoTerm } from "./HpoTerm";
@@ -66,7 +66,7 @@ export const SampleTable: Component<{
66
66
  <tr>
67
67
  <td>{sample.data.person.familyId}</td>
68
68
  <td>
69
- <Link href={`/samples/${sample.id}`}>{getSampleLabel(sample.data)}</Link>
69
+ <a href={`/samples/${sample.id}`}>{getSampleLabel(sample.data)}</a>
70
70
  </td>
71
71
  <td>{sampleFatherLabel(sample.data)}</td>
72
72
  <td>{sampleMotherLabel(sample.data)}</td>
@@ -6,7 +6,7 @@ import { FieldHeader } from "./FieldHeader";
6
6
  import { Record } from "@molgenis/vip-report-vcf/src/Vcf";
7
7
  import { Item } from "@molgenis/vip-report-api/src/Api";
8
8
  import { isCsqInfo } from "../utils/csqUtils";
9
- import { Link, useLocation } from "@solidjs/router";
9
+ import { useLocation } from "@solidjs/router";
10
10
 
11
11
  function isNonEmptyNestedInfoItem(nestedInfoField: FieldMetadata, index: number, value: Value[] | Value[][]): boolean {
12
12
  const infoField = nestedInfoField.nested?.items[index];
@@ -87,7 +87,7 @@ export const VariantInfoNestedTable: Component<{
87
87
  {isNonEmptyNestedInfoItem(props.infoField, i(), props.infoValue) && (
88
88
  <td>
89
89
  {isCsqInfo(infoFieldItem, "Consequence") ? (
90
- <Link href={`${useLocation().pathname}/consequences/${j()}`}>
90
+ <a href={`${useLocation().pathname}/consequences/${j()}`}>
91
91
  <Info
92
92
  info={{
93
93
  value: Array.isArray(value) ? value[i()] : null,
@@ -97,7 +97,7 @@ export const VariantInfoNestedTable: Component<{
97
97
  infoMeta={infoFieldItem}
98
98
  context={{}}
99
99
  />
100
- </Link>
100
+ </a>
101
101
  ) : (
102
102
  <Info
103
103
  info={{
@@ -2,7 +2,6 @@ import { Genotype, Metadata, Record } from "@molgenis/vip-report-vcf/src/Vcf";
2
2
  import { Ref } from "./record/Ref";
3
3
  import { Chrom } from "./record/Chrom";
4
4
  import { Pos } from "./record/Pos";
5
- import { Link } from "@solidjs/router";
6
5
  import { HtsFileMetadata, Item, Sample } from "@molgenis/vip-report-api/src/Api";
7
6
  import { GenotypeField } from "./record/format/GenotypeField";
8
7
  import { InfoCollapsablePane } from "./InfoCollapsablePane";
@@ -93,11 +92,11 @@ export const VariantsSampleTable: Component<{
93
92
  {(record) => (
94
93
  <tr>
95
94
  <td>
96
- <Link href={`/samples/${props.item.id}/variants/${record.id}`}>
95
+ <a href={`/samples/${props.item.id}/variants/${record.id}`}>
97
96
  <Chrom value={record.data.c} />
98
97
  <span>:</span>
99
98
  <Pos value={record.data.p} />
100
- </Link>
99
+ </a>
101
100
  </td>
102
101
  <td>
103
102
  <Ref value={record.data.r} isAbbreviate={true} />
@@ -9,7 +9,6 @@ import { Qual } from "./record/Qual";
9
9
  import { Filter } from "./record/Filter";
10
10
  import { Info } from "./record/Info";
11
11
  import { FieldMetadata } from "@molgenis/vip-report-vcf/src/MetadataParser";
12
- import { Link } from "@solidjs/router";
13
12
  import { HtsFileMetadata, Item } from "@molgenis/vip-report-api/src/Api";
14
13
  import { FieldHeader } from "./FieldHeader";
15
14
  import { InfoCollapsablePane } from "./InfoCollapsablePane";
@@ -76,9 +75,9 @@ export const VariantsTable: Component<{
76
75
  <Chrom value={record.data.c} />
77
76
  </td>
78
77
  <td>
79
- <Link href={`/variants/${record.id}`}>
78
+ <a href={`/variants/${record.id}`}>
80
79
  <Pos value={record.data.p} />
81
- </Link>
80
+ </a>
82
81
  </td>
83
82
  <td>
84
83
  <Id value={record.data.i} />
@@ -2,7 +2,6 @@ import { Component, Match, Switch } from "solid-js";
2
2
  import { FieldMetadata } from "@molgenis/vip-report-vcf/src/MetadataParser";
3
3
  import { FilterCategorical } from "./FilterCategorical";
4
4
  import { FilterIntegerGq } from "./FilterIntegerGq";
5
- import { FilterIntegerDp } from "./FilterIntegerDp";
6
5
  import { Item, Query, Sample } from "@molgenis/vip-report-api/src/Api";
7
6
  import { FilterClinVar } from "./FilterClinVar";
8
7
  import { isAnyCsqInfo } from "../../utils/csqUtils";
@@ -28,9 +27,6 @@ export const Filter: Component<FilterProps> = (props) => {
28
27
  <Match when={props.field.id === "GQ"}>
29
28
  <FilterIntegerGq {...props} />
30
29
  </Match>
31
- <Match when={props.field.id === "DP"}>
32
- <FilterIntegerDp {...props} />
33
- </Match>
34
30
  <Match when={props.field.id === "VIAB"}>
35
31
  <FilterAllelicBalance {...props} />
36
32
  </Match>
@@ -15,18 +15,8 @@ function isAllelicImbalance(genotype: Genotype, allelicBalance: number | undefin
15
15
  return false;
16
16
  }
17
17
 
18
- function getTitle(lowReadDepth: boolean, allelicImbalance: boolean) {
19
- let title = "";
20
- if (lowReadDepth) {
21
- title = "Read depth < 20";
22
- }
23
- if (allelicImbalance) {
24
- if (lowReadDepth) {
25
- title = `${title}, `;
26
- }
27
- title = `${title}Allelic imbalance`;
28
- }
29
- return title;
18
+ function getTitle(allelicImbalance: boolean) {
19
+ return allelicImbalance ? `Allelic imbalance` : ``;
30
20
  }
31
21
 
32
22
  export const GenotypeField: Component<{
@@ -38,7 +28,6 @@ export const GenotypeField: Component<{
38
28
  readDepth: number | undefined | null;
39
29
  }> = (props) => {
40
30
  const allelicImbalance: boolean = isAllelicImbalance(props.genotype, props.allelicBalance);
41
- const lowReadDepth = props.readDepth !== undefined && props.readDepth !== null && props.readDepth < 20;
42
31
  return (
43
32
  <>
44
33
  <For each={props.genotype.a}>
@@ -54,8 +43,8 @@ export const GenotypeField: Component<{
54
43
  </>
55
44
  )}
56
45
  </For>
57
- <Show when={lowReadDepth || allelicImbalance}>
58
- <abbr title={getTitle(lowReadDepth, allelicImbalance)} class="ml-1 is-clickable">
46
+ <Show when={allelicImbalance}>
47
+ <abbr title={getTitle(allelicImbalance)} class="ml-1 is-clickable">
59
48
  <i class="fas fa-circle-exclamation has-text-danger" />
60
49
  </abbr>
61
50
  </Show>
package/src/index.tsx CHANGED
@@ -18,6 +18,19 @@ import {
18
18
  faSearch,
19
19
  } from "@fortawesome/free-solid-svg-icons";
20
20
  import { Provider } from "./store";
21
+ import { ErrorBoundary } from "solid-js";
22
+ import { Error } from "./components/Error";
23
+ import { HashRouter, Route } from "@solidjs/router";
24
+ import { Home } from "./views/Home";
25
+ import { Samples } from "./views/Samples";
26
+ import { Sample } from "./views/Sample";
27
+ import { SampleVariantsView } from "./views/SampleVariants";
28
+ import { SampleVariantView } from "./views/SampleVariant";
29
+ import { SampleVariantConsequenceView } from "./views/SampleVariantConsequence";
30
+ import { VariantsView } from "./views/Variants";
31
+ import { Variant } from "./views/Variant";
32
+ import { VariantConsequence } from "./views/VariantConsequence";
33
+ import { Help } from "./views/Help";
21
34
 
22
35
  library.add(
23
36
  faAngleDown,
@@ -46,7 +59,36 @@ if (document.readyState === "complete") {
46
59
  render(
47
60
  () => (
48
61
  <Provider>
49
- <App />
62
+ <ErrorBoundary fallback={(err) => <Error error={err as unknown} />}>
63
+ <HashRouter root={App}>
64
+ <Route path="/" component={Home} />
65
+ <Route path="/samples">
66
+ <Route path="/" component={Samples} />
67
+ <Route path="/:sampleId">
68
+ <Route path="/" component={Sample} />
69
+ <Route path="/variants">
70
+ <Route path="/" component={SampleVariantsView} />
71
+ <Route path="/:variantId">
72
+ <Route path="/" component={SampleVariantView} />
73
+ <Route path="/consequences">
74
+ <Route path="/:consequenceId" component={SampleVariantConsequenceView} />
75
+ </Route>
76
+ </Route>
77
+ </Route>
78
+ </Route>
79
+ </Route>
80
+ <Route path="/variants">
81
+ <Route path="/" component={VariantsView} />
82
+ <Route path="/:variantId">
83
+ <Route path="/" component={Variant} />
84
+ <Route path="/consequences">
85
+ <Route path="/:consequenceId" component={VariantConsequence} />
86
+ </Route>
87
+ </Route>
88
+ </Route>
89
+ <Route path="/help" component={Help} />
90
+ </HashRouter>
91
+ </ErrorBoundary>
50
92
  </Provider>
51
93
  ),
52
94
  document.body,
@@ -1,4 +1,3 @@
1
- import { hashIntegration, Router } from "@solidjs/router";
2
1
  import { Context, createContext, ParentComponent, useContext } from "solid-js";
3
2
  import { createStore } from "solid-js/store";
4
3
  import { Item, Query, Sample, SortOrder } from "@molgenis/vip-report-api/src/Api";
@@ -172,11 +171,7 @@ export const Provider: ParentComponent = (props) => {
172
171
  };
173
172
  const store: AppStore = [state, actions];
174
173
 
175
- return (
176
- <Router source={hashIntegration()}>
177
- <StoreContext.Provider value={store}>{props.children}</StoreContext.Provider>
178
- </Router>
179
- );
174
+ return <StoreContext.Provider value={store}>{props.children}</StoreContext.Provider>;
180
175
  };
181
176
 
182
177
  export function useStore() {
@@ -1,26 +1,30 @@
1
1
  import { Component, For, Show } from "solid-js";
2
- import { Link, useRouteData } from "@solidjs/router";
2
+ import { createAsync, RouteSectionProps } from "@solidjs/router";
3
3
  import { Loader } from "../components/Loader";
4
4
  import { Breadcrumb } from "../components/Breadcrumb";
5
- import { SampleRouteData } from "./data/SampleData";
5
+ import { getSample } from "./data/data";
6
6
 
7
- export const Sample: Component = () => {
8
- const { sample } = useRouteData<SampleRouteData>();
7
+ export const Sample: Component<RouteSectionProps> = (props) => {
8
+ const sample = createAsync(() => getSample(Number(props.params.sampleId)));
9
9
 
10
10
  return (
11
- <Show when={!sample.loading} fallback={<Loader />}>
12
- <Breadcrumb items={[{ href: "/samples", text: "Samples" }, { text: sample().data.person.individualId }]} />
13
- <p class="has-text-weight-semibold">Sample</p>
14
- <div class="columns">
15
- <div class="column is-1">
16
- <For each={Object.keys(sample().data.person)}>{(key) => <p>{key}</p>}</For>
17
- </div>
18
- <div class="column is-1">
19
- <For each={Object.values(sample().data.person)}>{(value) => <p>{value}</p>}</For>
20
- </div>
21
- </div>
22
- <br />
23
- <Link href={`/samples/${sample().id}/variants`}>Variants</Link>
11
+ <Show when={sample()} fallback={<Loader />}>
12
+ {(sample) => (
13
+ <>
14
+ <Breadcrumb items={[{ href: "/samples", text: "Samples" }, { text: sample().data.person.individualId }]} />
15
+ <p class="has-text-weight-semibold">Sample</p>
16
+ <div class="columns">
17
+ <div class="column is-1">
18
+ <For each={Object.keys(sample().data.person)}>{(key) => <p>{key}</p>}</For>
19
+ </div>
20
+ <div class="column is-1">
21
+ <For each={Object.values(sample().data.person)}>{(value) => <p>{value}</p>}</For>
22
+ </div>
23
+ </div>
24
+ <br />
25
+ <a href={`/samples/${sample().id}/variants`}>Variants</a>
26
+ </>
27
+ )}
24
28
  </Show>
25
29
  );
26
30
  };
@@ -1,5 +1,5 @@
1
1
  import { Component, createResource, For, Show } from "solid-js";
2
- import { useRouteData } from "@solidjs/router";
2
+ import { createAsync, RouteSectionProps } from "@solidjs/router";
3
3
  import { Loader } from "../components/Loader";
4
4
  import { GenomeBrowser } from "../components/GenomeBrowser";
5
5
  import { fetchPedigreeSamples, fetchRecordsMeta, getRecordLabel } from "../utils/ApiUtils";
@@ -11,36 +11,51 @@ import { getNestedInfoFieldsWithValues } from "../utils/field";
11
11
  import { VariantSampleTable } from "../components/VariantSampleTable";
12
12
  import { Breadcrumb } from "../components/Breadcrumb";
13
13
  import { getRecordSamples } from "../utils/viewUtils";
14
- import { SampleVariantRouteData } from "./data/SampleVariantData";
15
14
  import { getSampleLabel } from "../utils/sample";
16
15
  import { Item, Sample } from "@molgenis/vip-report-api/src/Api";
17
16
  import { Metadata, Record } from "@molgenis/vip-report-vcf/src/Vcf";
18
17
  import { Abbr } from "../components/Abbr";
18
+ import { getSample, getVariant } from "./data/data";
19
19
 
20
- export const SampleVariantView: Component = () => {
21
- const { sample, variant } = useRouteData<SampleVariantRouteData>();
20
+ export const SampleVariantView: Component<RouteSectionProps> = (props) => {
21
+ const sample = createAsync(() => getSample(Number(props.params.sampleId)));
22
+ const variant = createAsync(() => getVariant(Number(props.params.variantId)));
22
23
 
23
24
  const [pedigreeSamples] = createResource(sample, fetchPedigreeSamples);
24
25
  const [recordsMeta] = createResource(fetchRecordsMeta);
25
26
 
26
27
  return (
27
- <Show when={sample() && variant()} fallback={<Loader />}>
28
- <Breadcrumb
29
- items={[
30
- { href: "/samples", text: "Samples" },
31
- { href: `/samples/${sample()!.id}`, text: getSampleLabel(sample()!.data) },
32
- { href: `/samples/${sample()!.id}/variants`, text: "Variants" },
33
- { text: getRecordLabel(variant()!) },
34
- ]}
35
- />
36
- <Show when={pedigreeSamples() && recordsMeta()} fallback={<Loader />}>
37
- <SampleVariant
38
- sample={sample()!}
39
- pedigreeSamples={pedigreeSamples()!.items}
40
- recordsMeta={recordsMeta()!}
41
- record={variant()!}
42
- />
43
- </Show>
28
+ <Show when={sample()} fallback={<Loader />}>
29
+ {(sample) => (
30
+ <Show when={variant()} fallback={<Loader />}>
31
+ {(variant) => (
32
+ <>
33
+ <Breadcrumb
34
+ items={[
35
+ { href: "/samples", text: "Samples" },
36
+ { href: `/samples/${sample().id}`, text: getSampleLabel(sample().data) },
37
+ { href: `/samples/${sample().id}/variants`, text: "Variants" },
38
+ { text: getRecordLabel(variant()) },
39
+ ]}
40
+ />
41
+ <Show when={pedigreeSamples()} fallback={<Loader />}>
42
+ {(pedigreeSamples) => (
43
+ <Show when={recordsMeta()} fallback={<Loader />}>
44
+ {(recordsMeta) => (
45
+ <SampleVariant
46
+ sample={sample()}
47
+ pedigreeSamples={pedigreeSamples().items}
48
+ recordsMeta={recordsMeta()}
49
+ record={variant()}
50
+ />
51
+ )}
52
+ </Show>
53
+ )}
54
+ </Show>
55
+ </>
56
+ )}
57
+ </Show>
58
+ )}
44
59
  </Show>
45
60
  );
46
61
  };
@@ -1,13 +1,7 @@
1
1
  import { Component, createResource, Show } from "solid-js";
2
- import { useRouteData } from "@solidjs/router";
2
+ import { createAsync, RouteSectionProps } from "@solidjs/router";
3
3
  import { Loader } from "../components/Loader";
4
- import {
5
- fetchDecisionTree,
6
- fetchHtsFileMetadata,
7
- fetchPedigreeSamples,
8
- fetchRecordsMeta,
9
- getRecordLabel,
10
- } from "../utils/ApiUtils";
4
+ import { fetchDecisionTree, fetchPedigreeSamples, fetchRecordsMeta, getRecordLabel } from "../utils/ApiUtils";
11
5
  import { VariantTable } from "../components/VariantTable";
12
6
  import { VariantInfoTable } from "../components/VariantInfoTable";
13
7
  import { VariantSampleTable } from "../components/VariantSampleTable";
@@ -16,41 +10,58 @@ import { ConsequenceTable } from "../components/ConsequenceTable";
16
10
  import { getRecordSamples, getSpecificConsequence } from "../utils/viewUtils";
17
11
  import { DecisionTreePath } from "../components/tree/DecisionTreePath";
18
12
  import { getDecisionTreePath } from "../utils/decisionTreeUtils";
19
- import { SampleVariantConsequenceRouteData } from "./data/SampleVariantConsequenceData";
20
13
  import { getSampleLabel } from "../utils/sample";
21
14
  import { DecisionTree, Item, Sample } from "@molgenis/vip-report-api/src/Api";
22
15
  import { Metadata, Record } from "@molgenis/vip-report-vcf/src/Vcf";
23
16
  import { ValueArray } from "@molgenis/vip-report-vcf/src/ValueParser";
17
+ import { getSample, getVariant } from "./data/data";
24
18
 
25
- export const SampleVariantConsequenceView: Component = () => {
26
- const { sample, variant, consequenceId } = useRouteData<SampleVariantConsequenceRouteData>();
27
-
19
+ export const SampleVariantConsequenceView: Component<RouteSectionProps> = (props) => {
20
+ const sample = createAsync(() => getSample(Number(props.params.sampleId)));
21
+ const variant = createAsync(() => getVariant(Number(props.params.variantId)));
22
+ const consequenceId = () => Number(props.params.consequenceId);
28
23
  const [pedigreeSamples] = createResource(sample, fetchPedigreeSamples);
29
24
  const [recordsMeta] = createResource(fetchRecordsMeta);
30
25
  const [decisionTree] = createResource(fetchDecisionTree, { initialValue: null });
31
- const [htsFileMeta] = createResource(fetchHtsFileMetadata);
32
26
 
33
27
  return (
34
- <Show when={sample() && variant()} fallback={<Loader />}>
35
- <Breadcrumb
36
- items={[
37
- { href: "/samples", text: "Samples" },
38
- { href: `/samples/${sample()!.id}`, text: getSampleLabel(sample()!.data) },
39
- { href: `/samples/${sample()!.id}/variants`, text: "Variants" },
40
- { href: `/samples/${sample()!.id}/variants/${variant()!.id}`, text: getRecordLabel(variant()!) },
41
- { text: `Consequence #${consequenceId}` },
42
- ]}
43
- />
44
- <Show when={pedigreeSamples() && recordsMeta() && htsFileMeta()} fallback={<Loader />}>
45
- <SampleVariantConsequence
46
- sample={sample()!}
47
- pedigreeSamples={pedigreeSamples()!.items}
48
- recordsMeta={recordsMeta()!}
49
- variant={variant()!}
50
- consequenceId={consequenceId}
51
- decisionTree={decisionTree()}
52
- />
53
- </Show>
28
+ <Show when={sample()} fallback={<Loader />}>
29
+ {(sample) => (
30
+ <Show when={variant()} fallback={<Loader />}>
31
+ {(variant) => (
32
+ <>
33
+ <Breadcrumb
34
+ items={[
35
+ { href: "/samples", text: "Samples" },
36
+ { href: `/samples/${sample().id}`, text: getSampleLabel(sample().data) },
37
+ { href: `/samples/${sample().id}/variants`, text: "Variants" },
38
+ {
39
+ href: `/samples/${sample().id}/variants/${variant().id}`,
40
+ text: getRecordLabel(variant()),
41
+ },
42
+ { text: `Consequence #${consequenceId()}` },
43
+ ]}
44
+ />
45
+ <Show when={pedigreeSamples()} fallback={<Loader />}>
46
+ {(pedigreeSamples) => (
47
+ <Show when={recordsMeta()} fallback={<Loader />}>
48
+ {(recordsMeta) => (
49
+ <SampleVariantConsequence
50
+ sample={sample()}
51
+ pedigreeSamples={pedigreeSamples().items}
52
+ recordsMeta={recordsMeta()}
53
+ variant={variant()}
54
+ consequenceId={consequenceId()}
55
+ decisionTree={decisionTree()}
56
+ />
57
+ )}
58
+ </Show>
59
+ )}
60
+ </Show>
61
+ </>
62
+ )}
63
+ </Show>
64
+ )}
54
65
  </Show>
55
66
  );
56
67
  };
@@ -1,5 +1,4 @@
1
1
  import { Component, createMemo, createResource, createSignal, onMount, Show } from "solid-js";
2
- import { useRouteData } from "@solidjs/router";
3
2
  import {
4
3
  HtsFileMetadata,
5
4
  Item,
@@ -35,7 +34,6 @@ import { Breadcrumb } from "../components/Breadcrumb";
35
34
  import { FieldMetadata } from "@molgenis/vip-report-vcf/src/MetadataParser";
36
35
  import { FilterChangeEvent, FilterClearEvent, Filters } from "../components/filter/Filters";
37
36
  import { DIRECTION_ASCENDING, DIRECTION_DESCENDING } from "../utils/sortUtils";
38
- import { SampleRouteData } from "./data/SampleData";
39
37
  import { useStore } from "../store";
40
38
  import { Metadata } from "@molgenis/vip-report-vcf/src/Vcf";
41
39
  import {
@@ -49,9 +47,11 @@ import {
49
47
  import { arrayEquals } from "../utils/utils";
50
48
  import { getAllelicBalanceQuery } from "../components/filter/FilterAllelicBalance";
51
49
  import { RecordsPerPage, RecordsPerPageEvent } from "../components/RecordsPerPage";
50
+ import { createAsync, RouteSectionProps } from "@solidjs/router";
51
+ import { getSample } from "./data/data";
52
52
 
53
- export const SampleVariantsView: Component = () => {
54
- const { sample } = useRouteData<SampleRouteData>();
53
+ export const SampleVariantsView: Component<RouteSectionProps> = (props) => {
54
+ const sample = createAsync(() => getSample(Number(props.params.sampleId)));
55
55
 
56
56
  const [pedigreeSamples] = createResource(sample, fetchPedigreeSamples);
57
57
  const [samplePhenotypes] = createResource(sample, fetchPhenotypicFeatures);
@@ -375,8 +375,8 @@ export const SampleVariants: Component<{
375
375
  };
376
376
 
377
377
  return (
378
- <div class="columns is-variable is-1">
379
- <div class="column is-1-fullhd is-2">
378
+ <div class="variants columns is-variable is-1">
379
+ <div class="scrolling-div column is-1-fullhd is-2">
380
380
  <SearchBox value={searchQuery()} onInput={onSearchChange} />
381
381
  <Filters
382
382
  fields={filterInfoFields()}
@@ -386,7 +386,7 @@ export const SampleVariants: Component<{
386
386
  onClear={onFilterClear}
387
387
  />
388
388
  </div>
389
- <div class="column">
389
+ <div class="scrolling-div column">
390
390
  <div class="columns is-gapless">
391
391
  <div class="column">
392
392
  <p class="title is-3">{title()}</p>
@@ -1,5 +1,5 @@
1
1
  import { Component, createResource, For, Show } from "solid-js";
2
- import { useRouteData } from "@solidjs/router";
2
+ import { createAsync, RouteSectionProps } from "@solidjs/router";
3
3
  import { GenomeBrowser } from "../components/GenomeBrowser";
4
4
  import { Loader } from "../components/Loader";
5
5
  import { Value } from "@molgenis/vip-report-vcf/src/ValueParser";
@@ -9,54 +9,60 @@ import { VariantInfoNestedTable } from "../components/VariantInfoNestedTable";
9
9
  import { getNestedInfoFieldsWithValues } from "../utils/field";
10
10
  import { Breadcrumb } from "../components/Breadcrumb";
11
11
  import { EMPTY_RECORDS_METADATA, fetchRecordsMeta, getRecordLabel } from "../utils/ApiUtils";
12
- import { VariantRouteData } from "./data/VariantData";
12
+ import { getVariant } from "./data/data";
13
+ import { Item } from "@molgenis/vip-report-api/src/Api";
14
+ import { Record } from "@molgenis/vip-report-vcf/src/Vcf";
13
15
 
14
- export const Variant: Component = () => {
15
- const { variant } = useRouteData<VariantRouteData>();
16
+ export const Variant: Component<RouteSectionProps<Promise<Item<Record>>>> = (props) => {
17
+ const variant = createAsync(() => getVariant(Number(props.params.variantId)));
16
18
 
17
19
  const [recordsMetadata] = createResource(fetchRecordsMeta, { initialValue: EMPTY_RECORDS_METADATA });
18
20
 
19
21
  return (
20
22
  <>
21
- <Show when={!variant.loading} fallback={<Loader />}>
22
- <Breadcrumb items={[{ href: "/variants", text: "Variants" }, { text: getRecordLabel(variant()) }]} />
23
- <GenomeBrowser contig={variant().data.c} position={variant().data.p} samples={[]} />
24
- <div class="columns">
25
- <div class="column is-3">
26
- <h1 class="title is-5">Record</h1>
27
- <VariantTable variant={variant().data} />
28
- </div>
29
- <Show
30
- when={
31
- Object.values(recordsMetadata().info).filter(
32
- (info) => !info.nested && variant().data.n[info.id] !== undefined,
33
- ).length > 0
34
- }
35
- >
36
- <div class="column is-3">
37
- <h1 class="title is-5">Info</h1>
38
- <VariantInfoTable infoFields={recordsMetadata().info} record={variant()} />
23
+ <Show when={variant()} fallback={<Loader />}>
24
+ {(variant) => (
25
+ <>
26
+ <Breadcrumb items={[{ href: "/variants", text: "Variants" }, { text: getRecordLabel(variant()) }]} />
27
+ <GenomeBrowser contig={variant().data.c} position={variant().data.p} samples={[]} />
28
+ <div class="columns">
29
+ <div class="column is-3">
30
+ <h1 class="title is-5">Record</h1>
31
+ <VariantTable variant={variant().data} />
32
+ </div>
33
+ <Show
34
+ when={
35
+ Object.values(recordsMetadata().info).filter(
36
+ (info) => !info.nested && variant().data.n[info.id] !== undefined,
37
+ ).length > 0
38
+ }
39
+ >
40
+ <div class="column is-3">
41
+ <h1 class="title is-5">Info</h1>
42
+ <VariantInfoTable infoFields={recordsMetadata().info} record={variant()} />
43
+ </div>
44
+ </Show>
39
45
  </div>
40
- </Show>
41
- </div>
42
- <div class="columns">
43
- <div class="column" style={{ "max-width": "100%" }}>
44
- <For each={getNestedInfoFieldsWithValues(recordsMetadata().info, variant().data.n)}>
45
- {(infoField) => (
46
- <>
47
- <h1 class="title is-5">{infoField.id}</h1>
48
- <p class="mb-4">{infoField.description}</p>
49
- <VariantInfoNestedTable
50
- infoValue={variant().data.n[infoField.id] as unknown as Value[][]}
51
- infoField={infoField}
52
- record={variant()}
53
- sample={null}
54
- />
55
- </>
56
- )}
57
- </For>
58
- </div>
59
- </div>
46
+ <div class="columns">
47
+ <div class="column" style={{ "max-width": "100%" }}>
48
+ <For each={getNestedInfoFieldsWithValues(recordsMetadata().info, variant().data.n)}>
49
+ {(infoField) => (
50
+ <>
51
+ <h1 class="title is-5">{infoField.id}</h1>
52
+ <p class="mb-4">{infoField.description}</p>
53
+ <VariantInfoNestedTable
54
+ infoValue={variant().data.n[infoField.id] as unknown as Value[][]}
55
+ infoField={infoField}
56
+ record={variant()}
57
+ sample={null}
58
+ />
59
+ </>
60
+ )}
61
+ </For>
62
+ </div>
63
+ </div>
64
+ </>
65
+ )}
60
66
  </Show>
61
67
  </>
62
68
  );
@@ -1,5 +1,5 @@
1
1
  import { Component, createResource, Show } from "solid-js";
2
- import { useRouteData } from "@solidjs/router";
2
+ import { createAsync, RouteSectionProps } from "@solidjs/router";
3
3
  import { Loader } from "../components/Loader";
4
4
  import { DecisionTree } from "@molgenis/vip-report-api/src/Api";
5
5
  import { VariantTable } from "../components/VariantTable";
@@ -18,10 +18,11 @@ import {
18
18
  } from "../utils/ApiUtils";
19
19
  import { FieldMetadata } from "@molgenis/vip-report-vcf/src/MetadataParser";
20
20
  import { ValueArray } from "@molgenis/vip-report-vcf/src/ValueParser";
21
- import { VariantConsequenceRouteData } from "./data/VariantConsequenceData";
21
+ import { getVariant } from "./data/data";
22
22
 
23
- export const VariantConsequence: Component = () => {
24
- const { variant, consequenceId } = useRouteData<VariantConsequenceRouteData>();
23
+ export const VariantConsequence: Component<RouteSectionProps> = (props) => {
24
+ const variant = createAsync(() => getVariant(Number(props.params.variantId)));
25
+ const consequenceId = () => Number(props.params.consequenceId);
25
26
 
26
27
  const [recordsMetadata] = createResource(fetchRecordsMeta, { initialValue: EMPTY_RECORDS_METADATA });
27
28
  const [decisionTree] = createResource(fetchDecisionTree, { initialValue: EMPTY_DECISION_TREE });
@@ -30,14 +31,14 @@ export const VariantConsequence: Component = () => {
30
31
 
31
32
  const hasDecisionTreePathMeta = () => csqFields().findIndex((csq) => csq.id === "VIPP") !== -1;
32
33
  return (
33
- <Show when={!variant.loading && variant()} fallback={<Loader />} keyed>
34
+ <Show when={variant()} fallback={<Loader />} keyed>
34
35
  {(variant) => (
35
36
  <>
36
37
  <Breadcrumb
37
38
  items={[
38
39
  { href: "/variants", text: "Variants" },
39
40
  { href: `/variants/${variant.id}`, text: getRecordLabel(variant) },
40
- { text: `Consequence #${consequenceId}` },
41
+ { text: `Consequence #${consequenceId()}` },
41
42
  ]}
42
43
  />
43
44
  <div class="columns">
@@ -45,7 +46,7 @@ export const VariantConsequence: Component = () => {
45
46
  <h1 class="title is-5">Consequence</h1>
46
47
  <ConsequenceTable
47
48
  csqMetadata={csqFields()}
48
- csqValues={getSpecificConsequence(variant.data.n.CSQ as ValueArray, consequenceId)}
49
+ csqValues={getSpecificConsequence(variant.data.n.CSQ as ValueArray, consequenceId())}
49
50
  record={variant}
50
51
  />
51
52
  </div>
@@ -56,7 +57,7 @@ export const VariantConsequence: Component = () => {
56
57
  <h1 class="title is-5">Classification tree path</h1>
57
58
  <DecisionTreePath
58
59
  decisionTree={decisionTree}
59
- path={getDecisionTreePath(recordsMetadata(), variant, consequenceId)}
60
+ path={getDecisionTreePath(recordsMetadata(), variant, consequenceId())}
60
61
  />
61
62
  </div>
62
63
  )}
@@ -83,7 +83,7 @@ export const Variants: Component<{
83
83
 
84
84
  return (
85
85
  <div class="columns is-variable is-1">
86
- <div class="column is-1-fullhd is-2">
86
+ <div class="scrolling-div column is-1-fullhd is-2">
87
87
  <SearchBox onInput={onSearchChange} />
88
88
  <InfoFilters
89
89
  fields={flattenFieldMetadata(props.recordsMeta.info)}
@@ -92,7 +92,7 @@ export const Variants: Component<{
92
92
  onClear={onFilterClear}
93
93
  />
94
94
  </div>
95
- <div class="column">
95
+ <div class="scrolling-div column">
96
96
  <div class="columns is-gapless">
97
97
  <div class="column">
98
98
  <p class="title is-3">Reported variants</p>
@@ -0,0 +1,7 @@
1
+ import { cache } from "@solidjs/router";
2
+ import { Item, Sample } from "@molgenis/vip-report-api/src/Api";
3
+ import { Record } from "@molgenis/vip-report-vcf/src/Vcf";
4
+ import api from "../../Api";
5
+
6
+ export const getSample = cache(async (id: number): Promise<Item<Sample>> => api.getSampleById(id), "sample");
7
+ export const getVariant = cache(async (id: number): Promise<Item<Record>> => api.getRecordById(id), "variant");
@@ -1,47 +0,0 @@
1
- import { Component } from "solid-js";
2
- import { FilterProps } from "./Filter";
3
- import { Checkbox, CheckboxEvent } from "../Checkbox";
4
- import { selector, selectorKey } from "../../utils/query";
5
- import { Item, Sample, Selector } from "@molgenis/vip-report-api/src/Api";
6
-
7
- export const FilterIntegerDp: Component<FilterProps> = (props) => {
8
- const onFilterChange = (event: CheckboxEvent) => {
9
- const fieldSelector: Selector = ["s", (props.sample as Item<Sample>).data.index, ...selector(props.field)];
10
- if (event.checked)
11
- props.onChange({
12
- key: selectorKey(fieldSelector),
13
- query: {
14
- operator: "or",
15
- args: [
16
- {
17
- selector: fieldSelector,
18
- operator: ">=",
19
- args: 20,
20
- },
21
- {
22
- selector: fieldSelector,
23
- operator: "==",
24
- args: null,
25
- },
26
- {
27
- selector: fieldSelector,
28
- operator: "==",
29
- args: undefined,
30
- },
31
- ],
32
- },
33
- });
34
- else props.onClear({ key: selectorKey(fieldSelector) });
35
- };
36
-
37
- return (
38
- <div class="control">
39
- <Checkbox
40
- desc="Sequencing depth >= 20"
41
- label="Depth >= 20"
42
- checked={props.query && props.query.args !== undefined}
43
- onChange={onFilterChange}
44
- />
45
- </div>
46
- );
47
- };
@@ -1,13 +0,0 @@
1
- import { createResource, Resource } from "solid-js";
2
- import { RouteDataFuncArgs } from "@solidjs/router/dist/types";
3
- import { EMPTY_SAMPLE_ITEM, fetchSampleById } from "../../utils/ApiUtils";
4
- import { Item, Sample } from "@molgenis/vip-report-api/src/Api";
5
-
6
- export type SampleParams = { sampleId: string };
7
- export type SampleRouteData = { sample: Resource<Item<Sample>> };
8
-
9
- export default function SampleData({ params }: RouteDataFuncArgs): SampleRouteData {
10
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
11
- const [sample] = createResource(() => params.sampleId, fetchSampleById, { initialValue: EMPTY_SAMPLE_ITEM });
12
- return { sample };
13
- }
@@ -1,13 +0,0 @@
1
- import { RouteDataFuncArgs } from "@solidjs/router/dist/types";
2
- import { SampleVariantRouteData } from "./SampleVariantData";
3
-
4
- export type SampleVariantConsequenceRouteData = { consequenceId: number } & SampleVariantRouteData;
5
-
6
- export default function SampleVariantConsequenceData({
7
- params,
8
- data,
9
- }: RouteDataFuncArgs): SampleVariantConsequenceRouteData {
10
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument
11
- const consequenceId: number = parseInt(params.consequenceId);
12
- return { ...(data as SampleVariantRouteData), consequenceId };
13
- }
@@ -1,14 +0,0 @@
1
- import { createResource, Resource } from "solid-js";
2
- import { RouteDataFuncArgs } from "@solidjs/router/dist/types";
3
- import { fetchRecordById } from "../../utils/ApiUtils";
4
- import { SampleRouteData } from "./SampleData";
5
- import { Item } from "@molgenis/vip-report-api/src/Api";
6
- import { Record } from "@molgenis/vip-report-vcf/src/Vcf";
7
-
8
- export type SampleVariantRouteData = SampleRouteData & { variant: Resource<Item<Record> | undefined> };
9
-
10
- export default function SampleVariantData({ params, data }: RouteDataFuncArgs): SampleVariantRouteData {
11
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
12
- const [variant] = createResource(() => params.variantId, fetchRecordById);
13
- return { ...(data as SampleRouteData), variant };
14
- }
@@ -1,10 +0,0 @@
1
- import { RouteDataFuncArgs } from "@solidjs/router/dist/types";
2
- import { VariantRouteData } from "./VariantData";
3
-
4
- export type VariantConsequenceRouteData = { consequenceId: number } & VariantRouteData;
5
-
6
- export default function VariantConsequenceData({ params, data }: RouteDataFuncArgs): VariantConsequenceRouteData {
7
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument
8
- const consequenceId: number = parseInt(params.consequenceId);
9
- return { ...(data as VariantRouteData), consequenceId };
10
- }
@@ -1,13 +0,0 @@
1
- import { createResource, Resource } from "solid-js";
2
- import { RouteDataFuncArgs } from "@solidjs/router/dist/types";
3
- import { EMPTY_RECORD_ITEM, fetchRecordById } from "../../utils/ApiUtils";
4
- import { Item } from "@molgenis/vip-report-api/src/Api";
5
- import { Record } from "@molgenis/vip-report-vcf/src/Vcf";
6
-
7
- export type VariantRouteData = { variant: Resource<Item<Record>> };
8
-
9
- export default function VariantData({ params }: RouteDataFuncArgs): VariantRouteData {
10
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
11
- const [variant] = createResource(() => params.variantId, fetchRecordById, { initialValue: EMPTY_RECORD_ITEM });
12
- return { variant };
13
- }