@molgenis/vip-report-template 6.1.1 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nvmrc +1 -1
- package/.travis.yml +9 -11
- package/README.md +411 -1
- package/eslint.config.mjs +11 -0
- package/package.json +40 -35
- package/scripts/deploy_npm_registry.sh +5 -0
- package/src/App.tsx +35 -29
- package/src/assets/sass/main.scss +12 -4
- package/src/components/Allele.tsx +95 -0
- package/src/components/Anchor.tsx +1 -1
- package/src/components/Breadcrumb.tsx +8 -5
- package/src/components/DatasetDropdown.tsx +10 -23
- package/src/components/ErrorNotification.tsx +9 -0
- package/src/components/GenomeBrowser.tsx +40 -23
- package/src/components/HpoTerm.tsx +1 -1
- package/src/components/{record/Pager.tsx → Pager.tsx} +21 -14
- package/src/components/RecordsPerPage.tsx +9 -7
- package/src/components/RecordsTable.tsx +130 -0
- package/src/components/SampleTable.tsx +70 -98
- package/src/components/SearchBox.tsx +8 -2
- package/src/components/Sort.tsx +28 -25
- package/src/components/Table.tsx +16 -0
- package/src/components/Tooltip.tsx +20 -0
- package/src/components/VariantBreadcrumb.tsx +54 -0
- package/src/components/VariantConsequenceContainer.tsx +100 -0
- package/src/components/VariantConsequenceTable.tsx +58 -0
- package/src/components/VariantContainer.tsx +71 -0
- package/src/components/VariantFilters.tsx +27 -0
- package/src/components/VariantGenotypeTable.tsx +44 -0
- package/src/components/VariantInfoTable.tsx +24 -33
- package/src/components/VariantResults.tsx +103 -0
- package/src/components/VariantTable.tsx +62 -66
- package/src/components/VariantTypeSelect.tsx +34 -0
- package/src/components/VariantsContainer.tsx +150 -0
- package/src/components/VariantsContainerHeader.tsx +70 -0
- package/src/components/field/Field.tsx +80 -0
- package/src/components/field/FieldAlt.tsx +19 -0
- package/src/components/field/FieldChrom.tsx +6 -0
- package/src/components/{record/Id.tsx → field/FieldFilter.tsx} +2 -1
- package/src/components/field/FieldFormat.tsx +10 -0
- package/src/components/{record/Filter.tsx → field/FieldId.tsx} +1 -1
- package/src/components/field/FieldPos.tsx +6 -0
- package/src/components/field/FieldQual.tsx +6 -0
- package/src/components/field/FieldRef.tsx +8 -0
- package/src/components/field/composed/FieldClinVar.tsx +72 -0
- package/src/components/field/composed/FieldComposed.tsx +68 -0
- package/src/components/field/composed/FieldGene.tsx +39 -0
- package/src/components/field/composed/FieldGenotype.tsx +35 -0
- package/src/components/{record/format/GenotypeField.tsx → field/composed/FieldGenotypeSnvSv.tsx} +20 -16
- package/src/components/field/composed/FieldGenotypeStr.tsx +31 -0
- package/src/components/field/composed/FieldGnomAd.tsx +58 -0
- package/src/components/field/composed/FieldHpo.tsx +50 -0
- package/src/components/field/composed/FieldInheritanceModes.tsx +32 -0
- package/src/components/field/composed/FieldLocus.tsx +18 -0
- package/src/components/field/composed/FieldVipC.tsx +25 -0
- package/src/components/field/composed/FieldVipCS.tsx +15 -0
- package/src/components/field/composed/FieldVkgl.tsx +37 -0
- package/src/components/field/genotype/FieldGenotype.tsx +19 -0
- package/src/components/field/genotype/FieldGenotypeType.tsx +9 -0
- package/src/components/field/info/FieldConsequence.tsx +15 -0
- package/src/components/{record/info/Hgvs.tsx → field/info/FieldHgvs.tsx} +4 -6
- package/src/components/field/info/FieldInfo.tsx +27 -0
- package/src/components/{record/info/PubMed.tsx → field/info/FieldPubMed.tsx} +4 -7
- package/src/components/field/typed/FieldCategorical.tsx +17 -0
- package/src/components/{record/field/FieldValueCharacter.tsx → field/typed/FieldCharacter.tsx} +3 -2
- package/src/components/{record/field/FieldValueFlag.tsx → field/typed/FieldFlag.tsx} +3 -2
- package/src/components/{record/field/FieldValueFloat.tsx → field/typed/FieldFloat.tsx} +3 -2
- package/src/components/{record/field/FieldValueInteger.tsx → field/typed/FieldInteger.tsx} +3 -2
- package/src/components/{record/field/FieldValueString.tsx → field/typed/FieldString.tsx} +3 -2
- package/src/components/field/typed/FieldTyped.tsx +20 -0
- package/src/components/field/typed/FieldTypedItem.tsx +49 -0
- package/src/components/field/typed/FieldTypedMultiple.tsx +21 -0
- package/src/components/filter/Filter.tsx +56 -48
- package/src/components/filter/FilterWrapper.scss +23 -0
- package/src/components/filter/FilterWrapper.tsx +63 -0
- package/src/components/filter/composed/FilterAllelicImbalance.tsx +26 -0
- package/src/components/filter/composed/FilterComposed.tsx +92 -0
- package/src/components/filter/composed/FilterDeNovo.tsx +35 -0
- package/src/components/filter/composed/FilterHpo.tsx +16 -0
- package/src/components/filter/composed/FilterInheritance.tsx +42 -0
- package/src/components/filter/composed/FilterLocus.tsx +75 -0
- package/src/components/filter/composed/FilterVipC.tsx +16 -0
- package/src/components/filter/composed/FilterVipCS.tsx +16 -0
- package/src/components/filter/fixed/FilterAlt.tsx +20 -0
- package/src/components/filter/fixed/FilterChrom.tsx +22 -0
- package/src/components/filter/fixed/FilterFilter.tsx +20 -0
- package/src/components/filter/fixed/FilterFixed.tsx +96 -0
- package/src/components/filter/fixed/FilterId.tsx +20 -0
- package/src/components/filter/fixed/FilterPos.tsx +22 -0
- package/src/components/filter/fixed/FilterQual.tsx +21 -0
- package/src/components/filter/fixed/FilterRef.tsx +22 -0
- package/src/components/filter/typed/FilterCategorical.tsx +119 -0
- package/src/components/filter/typed/FilterFlag.tsx +23 -0
- package/src/components/filter/typed/FilterInterval.tsx +72 -0
- package/src/components/filter/typed/FilterString.tsx +43 -0
- package/src/components/filter/typed/FilterTyped.tsx +56 -0
- package/src/components/form/ButtonApply.tsx +11 -0
- package/src/components/form/ButtonDownload.tsx +11 -0
- package/src/components/form/ButtonReset.tsx +9 -0
- package/src/components/{Checkbox.tsx → form/Checkbox.tsx} +4 -9
- package/src/components/form/Input.tsx +19 -0
- package/src/components/form/Select.scss +7 -0
- package/src/components/form/Select.tsx +34 -0
- package/src/components/tree/DecisionTreeBoolMultiQuery.tsx +1 -1
- package/src/components/tree/DecisionTreeBoolQuery.tsx +1 -1
- package/src/components/tree/DecisionTreeNode.tsx +41 -39
- package/src/components/tree/DecisionTreeNodeBool.tsx +1 -1
- package/src/components/tree/DecisionTreeNodeBoolMulti.tsx +1 -1
- package/src/components/tree/DecisionTreeNodeCategorical.tsx +1 -1
- package/src/components/tree/DecisionTreeNodeExists.tsx +1 -1
- package/src/components/tree/DecisionTreeNodeLeaf.tsx +1 -1
- package/src/components/tree/DecisionTreeOutcomeNode.tsx +1 -1
- package/src/components/tree/DecisionTreePath.tsx +1 -1
- package/src/igv.d.ts +2 -1
- package/src/index.tsx +48 -19
- package/src/mocks/GRCh37/decisionTree.json +23 -22
- package/src/mocks/GRCh37/field_metadata.json +435 -95
- package/src/mocks/GRCh37/sampleTree.json +143 -0
- package/src/mocks/GRCh37/static.ts +63 -133
- package/src/mocks/GRCh37/vcf/family.vcf.blob +37 -31
- package/src/mocks/GRCh38/decisionTree.json +52 -33
- package/src/mocks/GRCh38/decisionTreeStr.json +572 -0
- package/src/mocks/GRCh38/fasta/chr1_149380406-149403321.fasta.gz.blob +0 -0
- package/src/mocks/GRCh38/field_metadata.json +435 -95
- package/src/mocks/GRCh38/sampleTree.json +175 -0
- package/src/mocks/GRCh38/static.ts +101 -42
- package/src/mocks/GRCh38/str.cram.blob +0 -0
- package/src/mocks/GRCh38/str.cram.crai.blob +0 -0
- package/src/mocks/GRCh38/vcf/family.vcf.blob +25 -24
- package/src/mocks/GRCh38/vcf/no_vep.vcf.blob +29 -28
- package/src/mocks/GRCh38/vcf/samples_0.vcf.blob +28 -27
- package/src/mocks/GRCh38/vcf/samples_1.vcf.blob +29 -28
- package/src/mocks/GRCh38/vcf/samples_100.vcf.blob +28 -27
- package/src/mocks/GRCh38/vcf/str.vcf.blob +321 -0
- package/src/mocks/MockApiClient.ts +341 -328
- package/src/mocks/config_cram.json +701 -0
- package/src/mocks/config_vcf.json +699 -0
- package/src/store/app.ts +30 -0
- package/src/store/index.tsx +3 -168
- package/src/store/variants.ts +182 -0
- package/src/types/config.d.ts +190 -0
- package/src/types/configCellComposed.d.ts +86 -0
- package/src/types/configCells.d.ts +129 -0
- package/src/types/configFilter.d.ts +80 -0
- package/src/types/configFilterComposed.d.ts +60 -0
- package/src/types/configSort.d.ts +13 -0
- package/src/types/filter.d.ts +17 -0
- package/src/types/store.d.ts +34 -0
- package/src/utils/api.ts +281 -0
- package/src/utils/config/config.ts +182 -0
- package/src/utils/config/configCells.ts +74 -0
- package/src/utils/config/configCellsComposed.ts +508 -0
- package/src/utils/config/configCellsField.ts +61 -0
- package/src/utils/config/configCellsFixed.ts +126 -0
- package/src/utils/config/configFilters.ts +46 -0
- package/src/utils/config/configFiltersComposed.ts +208 -0
- package/src/utils/config/configFiltersField.ts +49 -0
- package/src/utils/config/configFiltersFixed.ts +106 -0
- package/src/utils/config/configSorts.ts +44 -0
- package/src/utils/config/configValidator.ts +380 -0
- package/src/utils/config/configVip.ts +25 -0
- package/src/utils/csq.ts +115 -0
- package/src/utils/decisionTree.ts +45 -0
- package/src/utils/download.ts +30 -0
- package/src/utils/error.ts +69 -0
- package/src/utils/query/query.ts +55 -0
- package/src/utils/query/queryFilter.ts +132 -0
- package/src/utils/query/queryFilterComposed.ts +247 -0
- package/src/utils/query/queryFilterField.ts +75 -0
- package/src/utils/query/queryFilterFixed.ts +44 -0
- package/src/utils/query/querySample.ts +18 -0
- package/src/utils/query/queryVariantType.ts +76 -0
- package/src/utils/query/selector.ts +41 -0
- package/src/utils/{sortUtils.ts → query/sort.ts} +32 -11
- package/src/utils/sample.ts +19 -35
- package/src/utils/utils.ts +66 -2
- package/src/utils/variantType.ts +43 -0
- package/src/utils/vcf.ts +352 -0
- package/src/views/Help.tsx +109 -114
- package/src/views/Home.tsx +3 -2
- package/src/views/Sample.tsx +12 -7
- package/src/views/SampleVariant.tsx +23 -112
- package/src/views/SampleVariantConsequence.tsx +54 -114
- package/src/views/SampleVariants.tsx +33 -445
- package/src/views/SampleVariantsRedirect.tsx +20 -0
- package/src/views/Samples.tsx +7 -10
- package/src/views/Variant.tsx +31 -61
- package/src/views/VariantConsequence.tsx +42 -72
- package/src/views/Variants.tsx +29 -138
- package/src/views/VariantsRedirect.tsx +25 -0
- package/src/views/data/data.tsx +32 -6
- package/tests/store/variants.test.ts +122 -0
- package/tests/utils/config/config.test.ts +167 -0
- package/tests/utils/config/configCells.test.ts +86 -0
- package/tests/utils/config/configCellsComposed.test.ts +1163 -0
- package/tests/utils/config/configCellsField.test.ts +164 -0
- package/tests/utils/config/configCellsFixed.test.ts +99 -0
- package/tests/utils/config/configFilters.test.ts +80 -0
- package/tests/utils/config/configFiltersComposed.test.ts +504 -0
- package/tests/utils/config/configFiltersField.test.ts +140 -0
- package/tests/utils/config/configFiltersFixed.test.ts +81 -0
- package/tests/utils/config/configSorts.test.ts +55 -0
- package/tests/utils/config/configValidator.test.ts +56 -0
- package/tests/utils/config/configVip.test.ts +53 -0
- package/tests/utils/decisionTree.test.ts +71 -0
- package/tests/utils/download.test.ts +20 -0
- package/tests/utils/query/query.test.ts +84 -0
- package/tests/utils/query/queryFilter.test.ts +243 -0
- package/tests/utils/query/queryFilterComposed.test.ts +301 -0
- package/tests/utils/query/queryFilterField.test.ts +75 -0
- package/tests/utils/query/queryFilterFixed.test.ts +86 -0
- package/tests/utils/query/querySample.test.ts +45 -0
- package/tests/utils/query/queryVariantType.test.ts +56 -0
- package/{src/__tests__/sortUtils.test.ts → tests/utils/query/sort.test.ts} +3 -4
- package/tests/utils/sample.test.ts +259 -0
- package/tests/utils/utils.test.ts +120 -0
- package/tests/utils/variantType.test.ts +48 -0
- package/tests/utils/vcf.test.ts +649 -0
- package/tsconfig.json +6 -2
- package/vite.config.mts +20 -3
- package/.eslintignore +0 -4
- package/.eslintrc.js +0 -23
- package/src/Api.ts +0 -12
- package/src/__tests__/decisionTreeUtils.test.ts +0 -75
- package/src/__tests__/field.test.ts +0 -107
- package/src/__tests__/query.test.ts +0 -188
- package/src/__tests__/sample.test.ts +0 -184
- package/src/__tests__/utils.test.ts +0 -24
- package/src/__tests__/viewUtils.test.ts +0 -125
- package/src/components/ConsequenceTable.tsx +0 -45
- package/src/components/Error.tsx +0 -9
- package/src/components/FieldHeader.tsx +0 -26
- package/src/components/InfoCollapsablePane.tsx +0 -90
- package/src/components/VariantInfoNestedTable.tsx +0 -127
- package/src/components/VariantSampleTable.tsx +0 -58
- package/src/components/VariantsSampleTable.tsx +0 -183
- package/src/components/VariantsTable.tsx +0 -124
- package/src/components/filter/FilterAllelicBalance.tsx +0 -81
- package/src/components/filter/FilterCategorical.tsx +0 -81
- package/src/components/filter/FilterClinVar.tsx +0 -21
- package/src/components/filter/FilterGene.tsx +0 -34
- package/src/components/filter/FilterHpo.tsx +0 -161
- package/src/components/filter/FilterInheritance.tsx +0 -162
- package/src/components/filter/FilterIntegerGq.tsx +0 -47
- package/src/components/filter/FilterVI.tsx +0 -68
- package/src/components/filter/FilterVariantType.tsx +0 -146
- package/src/components/filter/Filters.tsx +0 -29
- package/src/components/filter/InfoFilter.tsx +0 -39
- package/src/components/filter/InfoFilters.tsx +0 -35
- package/src/components/filter/SampleFilters.tsx +0 -93
- package/src/components/filter/SamplesFilters.tsx +0 -33
- package/src/components/record/Allele.tsx +0 -38
- package/src/components/record/AlleleBreakend.tsx +0 -5
- package/src/components/record/AlleleMissing.tsx +0 -5
- package/src/components/record/AlleleNucs.tsx +0 -49
- package/src/components/record/AlleleSymbolic.tsx +0 -5
- package/src/components/record/Alt.tsx +0 -17
- package/src/components/record/Chrom.tsx +0 -5
- package/src/components/record/Format.tsx +0 -40
- package/src/components/record/Info.tsx +0 -55
- package/src/components/record/Pos.tsx +0 -5
- package/src/components/record/Qual.tsx +0 -5
- package/src/components/record/RecordDownload.tsx +0 -66
- package/src/components/record/Ref.tsx +0 -6
- package/src/components/record/field/Field.tsx +0 -36
- package/src/components/record/field/FieldMultipleValue.tsx +0 -22
- package/src/components/record/field/FieldSingleValue.tsx +0 -35
- package/src/components/record/info/ClinVar.tsx +0 -81
- package/src/components/record/info/Consequence.tsx +0 -18
- package/src/components/record/info/Gene.tsx +0 -56
- package/src/components/record/info/GnomAD.tsx +0 -54
- package/src/components/record/info/Hpo.tsx +0 -52
- package/src/components/record/info/InheritanceModes.tsx +0 -22
- package/src/components/record/info/VipC.tsx +0 -23
- package/src/components/record/info/Vkgl.tsx +0 -42
- package/src/mocks/GRCh37/vcf/no_vep.vcf.blob +0 -61
- package/src/mocks/GRCh37/vcf/samples_0.vcf.blob +0 -93
- package/src/mocks/GRCh37/vcf/samples_1.vcf.blob +0 -93
- package/src/mocks/GRCh37/vcf/samples_100.vcf.blob +0 -93
- package/src/utils/ApiUtils.ts +0 -259
- package/src/utils/csqUtils.ts +0 -27
- package/src/utils/decisionTreeUtils.ts +0 -14
- package/src/utils/field.ts +0 -49
- package/src/utils/query.ts +0 -154
- package/src/utils/viewUtils.ts +0 -32
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { FieldMetadata, InfoMetadata, RecordSampleType, VcfRecord } from "@molgenis/vip-report-vcf";
|
|
2
|
+
import { Item } from "@molgenis/vip-report-api";
|
|
3
|
+
import { CellValueCustom } from "./configCellComposed";
|
|
4
|
+
import { FieldValue } from "../utils/vcf.ts";
|
|
5
|
+
|
|
6
|
+
export type CellId = string;
|
|
7
|
+
export type CellType =
|
|
8
|
+
| "chrom"
|
|
9
|
+
| "pos"
|
|
10
|
+
| "id"
|
|
11
|
+
| "ref"
|
|
12
|
+
| "alt"
|
|
13
|
+
| "qual"
|
|
14
|
+
| "filter"
|
|
15
|
+
| "info"
|
|
16
|
+
| "format"
|
|
17
|
+
| "genotype"
|
|
18
|
+
| "composed";
|
|
19
|
+
|
|
20
|
+
interface ConfigCellBase<T extends CellValue> {
|
|
21
|
+
type: CellType;
|
|
22
|
+
label: () => string;
|
|
23
|
+
description: () => string | null;
|
|
24
|
+
value: (record: Item<VcfRecord>, valueIndex: number) => T;
|
|
25
|
+
valueCount: (record: Item<VcfRecord>) => number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type CellValueChrom = string;
|
|
29
|
+
|
|
30
|
+
export interface ConfigCellChrom extends ConfigCellBase<CellValueChrom> {
|
|
31
|
+
type: "chrom";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type CellValuePos = number;
|
|
35
|
+
|
|
36
|
+
export interface ConfigCellPos extends ConfigCellBase<CellValuePos> {
|
|
37
|
+
type: "pos";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type CellValueId = string[];
|
|
41
|
+
|
|
42
|
+
export interface ConfigCellId extends ConfigCellBase<CellValueId> {
|
|
43
|
+
type: "id";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type CellValueRef = string;
|
|
47
|
+
|
|
48
|
+
export interface ConfigCellRef extends ConfigCellBase<CellValueRef> {
|
|
49
|
+
type: "ref";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type CellValueAlt = (string | null)[];
|
|
53
|
+
|
|
54
|
+
export interface ConfigCellAlt extends ConfigCellBase<CellValueAlt> {
|
|
55
|
+
type: "alt";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type CellValueQual = number | null;
|
|
59
|
+
|
|
60
|
+
export interface ConfigCellQual extends ConfigCellBase<CellValueQual> {
|
|
61
|
+
type: "qual";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export type CellValueFilter = string[];
|
|
65
|
+
|
|
66
|
+
export interface ConfigCellFilter extends ConfigCellBase<string[]> {
|
|
67
|
+
type: "filter";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type ConfigCellFixed =
|
|
71
|
+
| ConfigCellChrom
|
|
72
|
+
| ConfigCellPos
|
|
73
|
+
| ConfigCellId
|
|
74
|
+
| ConfigCellRef
|
|
75
|
+
| ConfigCellAlt
|
|
76
|
+
| ConfigCellQual
|
|
77
|
+
| ConfigCellFilter;
|
|
78
|
+
|
|
79
|
+
export type CellValueInfo = FieldValue | undefined;
|
|
80
|
+
|
|
81
|
+
export interface ConfigCellInfo extends ConfigCellBase<CellValueInfo> {
|
|
82
|
+
type: "info";
|
|
83
|
+
field: InfoMetadata;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type CellValueFormat = string[];
|
|
87
|
+
|
|
88
|
+
export interface ConfigCellFormat extends ConfigCellBase<CellValueFormat> {
|
|
89
|
+
type: "format";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export type CellValueGenotype = RecordSampleType | undefined;
|
|
93
|
+
|
|
94
|
+
export interface ConfigCellGenotype extends ConfigCellBase<CellValueGenotype> {
|
|
95
|
+
type: "genotype";
|
|
96
|
+
field: FieldMetadata;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
interface ConfigCellCustom<T extends CellValueCustom> extends ConfigCellBase<T> {
|
|
100
|
+
type: "composed";
|
|
101
|
+
id: CellId;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export type ConfigCellItem =
|
|
105
|
+
| ConfigCellFixed
|
|
106
|
+
| ConfigCellFormat
|
|
107
|
+
| ConfigCellInfo
|
|
108
|
+
| ConfigCellGenotype
|
|
109
|
+
| ConfigCellCustom<CellValueCustom>;
|
|
110
|
+
|
|
111
|
+
export interface ConfigCellGroup {
|
|
112
|
+
type: "group";
|
|
113
|
+
fieldConfigs: ConfigCellItem[];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export type ConfigCell = ConfigCellItem | ConfigCellGroup;
|
|
117
|
+
|
|
118
|
+
export type CellValueFixed =
|
|
119
|
+
| CellValueChrom
|
|
120
|
+
| CellValuePos
|
|
121
|
+
| CellValueId
|
|
122
|
+
| CellValueRef
|
|
123
|
+
| CellValueAlt
|
|
124
|
+
| CellValueQual
|
|
125
|
+
| CellValueFilter;
|
|
126
|
+
|
|
127
|
+
export type CellValue = CellValueFixed | CellValueFormat | CellValueInfo | CellValueGenotype | CellValueCustom;
|
|
128
|
+
|
|
129
|
+
// note: add composed field to configCellComposed.d.ts
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ConfigFilterComposed, FilterValueComposed } from "./configFilterComposed";
|
|
2
|
+
import { SampleContainer } from "../utils/api.ts";
|
|
3
|
+
import { FieldMetadataWrapper } from "../utils/vcf.ts";
|
|
4
|
+
|
|
5
|
+
export type FilterId = string;
|
|
6
|
+
export type FilterType = "fixed" | "info" | "genotype" | "composed";
|
|
7
|
+
export type FilterCategoryId = string;
|
|
8
|
+
export type FilterCategory = {
|
|
9
|
+
id: FilterCategoryId;
|
|
10
|
+
label: string;
|
|
11
|
+
count?: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type FilterValueCategorical = FilterCategoryId[];
|
|
15
|
+
export type FilterValueString = string[];
|
|
16
|
+
export type ValueNumber = number | undefined;
|
|
17
|
+
export type FilterValueFlag = FilterValueCategorical;
|
|
18
|
+
export type FilterValueInterval = { left: ValueNumber; right: ValueNumber };
|
|
19
|
+
|
|
20
|
+
export type FilterValueChrom = FilterValueString;
|
|
21
|
+
export type FilterValuePos = FilterValueInterval;
|
|
22
|
+
export type FilterValueId = FilterValueString;
|
|
23
|
+
export type FilterValueRef = FilterValueString;
|
|
24
|
+
export type FilterValueAlt = FilterValueString;
|
|
25
|
+
export type FilterValueQual = FilterValueInterval;
|
|
26
|
+
export type FilterValueFilter = FilterValueString;
|
|
27
|
+
|
|
28
|
+
export type FilterValueFixed =
|
|
29
|
+
| FilterValueChrom
|
|
30
|
+
| FilterValuePos
|
|
31
|
+
| FilterValueId
|
|
32
|
+
| FilterValueRef
|
|
33
|
+
| FilterValueAlt
|
|
34
|
+
| FilterValueQual
|
|
35
|
+
| FilterValueFilter;
|
|
36
|
+
|
|
37
|
+
export type FilterValueField = FilterValueCategorical | FilterValueString | FilterValueInterval;
|
|
38
|
+
|
|
39
|
+
export type FilterValue = FilterValueFixed | FilterValueField | FilterValueComposed;
|
|
40
|
+
export type FilterValueMap = { [key: FilterId]: FilterValue };
|
|
41
|
+
|
|
42
|
+
export type ConfigFilterFixed =
|
|
43
|
+
| ConfigFilterChrom
|
|
44
|
+
| ConfigFilterPos
|
|
45
|
+
| ConfigFilterId
|
|
46
|
+
| ConfigFilterRef
|
|
47
|
+
| ConfigFilterAlt
|
|
48
|
+
| ConfigFilterQual
|
|
49
|
+
| ConfigFilterFilter;
|
|
50
|
+
|
|
51
|
+
export type ConfigFilter =
|
|
52
|
+
| ConfigFilterFixed
|
|
53
|
+
| ConfigFilterComposed
|
|
54
|
+
| ConfigFilterField // TODO rename to ConfigFilterInfo?
|
|
55
|
+
| ConfigFilterFormat; // TODO rename to ConfigFilterGenotype
|
|
56
|
+
|
|
57
|
+
export interface ConfigFilterBase {
|
|
58
|
+
type: FilterType;
|
|
59
|
+
id: FilterId;
|
|
60
|
+
label: () => string;
|
|
61
|
+
description: () => string | null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export type ConfigFilterChrom = ConfigFilterBase;
|
|
65
|
+
export type ConfigFilterPos = ConfigFilterBase;
|
|
66
|
+
export type ConfigFilterId = ConfigFilterBase;
|
|
67
|
+
export type ConfigFilterRef = ConfigFilterBase;
|
|
68
|
+
export type ConfigFilterAlt = ConfigFilterBase;
|
|
69
|
+
export type ConfigFilterQual = ConfigFilterBase;
|
|
70
|
+
export type ConfigFilterFilter = ConfigFilterBase;
|
|
71
|
+
|
|
72
|
+
export interface ConfigFilterField extends ConfigFilterBase {
|
|
73
|
+
field: FieldMetadataWrapper;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface ConfigFilterFormat extends ConfigFilterField {
|
|
77
|
+
sample: SampleContainer;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// note: add composed filters to configFilterComposed.d.ts
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConfigFilterBase,
|
|
3
|
+
ConfigFilterField,
|
|
4
|
+
ConfigFilterFormat,
|
|
5
|
+
FilterValueCategorical,
|
|
6
|
+
FilterValueFlag,
|
|
7
|
+
} from "./configFilter";
|
|
8
|
+
import { SampleContainer } from "../utils/api.ts";
|
|
9
|
+
import { FieldMetadataWrapper } from "../utils/vcf.ts";
|
|
10
|
+
|
|
11
|
+
export type ChromosomeId = string;
|
|
12
|
+
export type FilterValueHpo = FilterValueCategorical;
|
|
13
|
+
export type FilterValueLocus = { chromosome: ChromosomeId; start?: number; end?: number };
|
|
14
|
+
export type FilterValueVipC = FilterValueCategorical;
|
|
15
|
+
export type FilterValueVipCS = FilterValueCategorical;
|
|
16
|
+
export type FilterValueAllelicImbalance = FilterValueFlag;
|
|
17
|
+
export type FilterValueInheritanceMatch = FilterValueFlag;
|
|
18
|
+
export type FilterValueDeNovo = FilterValueFlag;
|
|
19
|
+
|
|
20
|
+
export type ConfigFilterComposed =
|
|
21
|
+
| ConfigFilterHpo
|
|
22
|
+
| ConfigFilterLocus
|
|
23
|
+
| ConfigFilterAllelicImbalance
|
|
24
|
+
| ConfigFilterInheritanceMatch
|
|
25
|
+
| ConfigFilterDeNovo
|
|
26
|
+
| ConfigFilterVipC
|
|
27
|
+
| ConfigFilterVipCS;
|
|
28
|
+
|
|
29
|
+
export type ConfigFilterHpo = ConfigFilterField;
|
|
30
|
+
|
|
31
|
+
export interface ConfigFilterAllelicImbalance extends ConfigFilterBase {
|
|
32
|
+
sample: SampleContainer;
|
|
33
|
+
viabField: FieldMetadataWrapper;
|
|
34
|
+
genotypeField: FieldMetadataWrapper;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ConfigFilterInheritanceMatch extends ConfigFilterBase {
|
|
38
|
+
sample: SampleContainer;
|
|
39
|
+
vimField: FieldMetadataWrapper;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ConfigFilterDeNovo extends ConfigFilterBase {
|
|
43
|
+
sample: SampleContainer;
|
|
44
|
+
vidField: FieldMetadataWrapper;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type ConfigFilterVipC = ConfigFilterField;
|
|
48
|
+
export type ConfigFilterVipCS = ConfigFilterFormat;
|
|
49
|
+
|
|
50
|
+
export interface ConfigFilterLocus extends ConfigFilterBase {
|
|
51
|
+
chromosomes: ChromosomeId[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type FilterValueComposed =
|
|
55
|
+
| FilterValueHpo
|
|
56
|
+
| FilterValueLocus
|
|
57
|
+
| FilterValueAllelicImbalance
|
|
58
|
+
| FilterValueInheritanceMatch
|
|
59
|
+
| FilterValueVipC
|
|
60
|
+
| FilterValueVipCS;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FieldMetadata } from "@molgenis/vip-report-vcf";
|
|
2
|
+
|
|
3
|
+
export interface ConfigSort {
|
|
4
|
+
selected: boolean | undefined;
|
|
5
|
+
orders: ConfigSortOrder[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ConfigSortOrder {
|
|
9
|
+
direction: "desc" | "asc";
|
|
10
|
+
field: FieldMetadata;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type ConfigSorts = ConfigSort[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FilterId, FilterValue } from "./configFilter";
|
|
2
|
+
|
|
3
|
+
export type FilterValueMap = { [key: FilterId]: FilterValue };
|
|
4
|
+
|
|
5
|
+
export interface FilterValueChangeEvent<FilterValueType> {
|
|
6
|
+
value: FilterValueType;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface FilterChangeEvent extends FilterValueChangeEvent<FilterValue> {
|
|
10
|
+
id: FilterId;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type FilterChangeCallback = (event: FilterChangeEvent) => void;
|
|
14
|
+
export type FilterClearEvent = {
|
|
15
|
+
id: FilterId;
|
|
16
|
+
};
|
|
17
|
+
export type FilterClearCallback = (event: FilterClearEvent) => void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SetStoreFunction } from "solid-js/store";
|
|
2
|
+
import { VariantTypeId } from "../utils/variantType.ts";
|
|
3
|
+
import { SortOrder } from "@molgenis/vip-report-api";
|
|
4
|
+
import { FilterValueMap } from "./filter";
|
|
5
|
+
|
|
6
|
+
export type Page = { number: number; size?: number };
|
|
7
|
+
export type Sort = SortOrder | SortOrder[];
|
|
8
|
+
export type AppStateVariantType = {
|
|
9
|
+
filterValues?: FilterValueMap;
|
|
10
|
+
page?: Page;
|
|
11
|
+
/**
|
|
12
|
+
* null: do not sort, the caller of this function should not fall back to a default sort
|
|
13
|
+
* undefined: sort behavior is undefined, the caller of this function could fall back to a default sort
|
|
14
|
+
*/
|
|
15
|
+
sort?: Sort | null;
|
|
16
|
+
};
|
|
17
|
+
export type AppStateVariantTypes = Partial<Record<VariantTypeId, AppStateVariantType>>;
|
|
18
|
+
type AppStateSamples = {
|
|
19
|
+
page?: number;
|
|
20
|
+
searchQuery?: string;
|
|
21
|
+
probandFilterValue?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export type AppState = {
|
|
24
|
+
variants: AppStateVariantTypes;
|
|
25
|
+
sampleVariants: Record<string, AppStateVariantTypes>;
|
|
26
|
+
samples: AppStateSamples;
|
|
27
|
+
};
|
|
28
|
+
export type AppActions = {
|
|
29
|
+
reset(): void;
|
|
30
|
+
setSamplePage(page: number): void;
|
|
31
|
+
setSampleSearchQuery(searchQuery: string): void;
|
|
32
|
+
setSampleProbandFilterValue(probandFilterValue: boolean): void;
|
|
33
|
+
};
|
|
34
|
+
export type AppStore = [state: AppState, actions: AppActions, setState: SetStoreFunction<AppState>];
|
package/src/utils/api.ts
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AppMetadata,
|
|
3
|
+
Cram,
|
|
4
|
+
DecisionTree,
|
|
5
|
+
HtsFileMetadata,
|
|
6
|
+
Item,
|
|
7
|
+
Json,
|
|
8
|
+
PagedItems,
|
|
9
|
+
Params,
|
|
10
|
+
PhenotypicFeature,
|
|
11
|
+
Query,
|
|
12
|
+
Sample,
|
|
13
|
+
WindowApiClient,
|
|
14
|
+
} from "@molgenis/vip-report-api";
|
|
15
|
+
import { isSampleFather, isSampleMother } from "./sample.ts";
|
|
16
|
+
import { NestedFieldMetadata, Value, VcfMetadata, VcfRecord } from "@molgenis/vip-report-vcf";
|
|
17
|
+
import { createRecordSort } from "./query/sort.ts";
|
|
18
|
+
import { createFieldMap, FieldMap, isNumerical } from "./vcf.ts";
|
|
19
|
+
import { compareCsq, compareCsqDefault } from "./csq.ts";
|
|
20
|
+
import { VariantTypeId } from "./variantType.ts";
|
|
21
|
+
import { MockApiClient } from "../mocks/MockApiClient.ts";
|
|
22
|
+
import { ConfigJson } from "../types/config";
|
|
23
|
+
import { RuntimeError } from "./error.ts";
|
|
24
|
+
import { validateConfig } from "./config/configValidator.ts";
|
|
25
|
+
|
|
26
|
+
export type VcfMetadataContainer = VcfMetadata & {
|
|
27
|
+
fieldMap: FieldMap;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Expose aggregate metadata container for convenience
|
|
31
|
+
*/
|
|
32
|
+
export type MetadataContainer = {
|
|
33
|
+
app: AppMetadata;
|
|
34
|
+
htsFile: HtsFileMetadata;
|
|
35
|
+
records: VcfMetadataContainer;
|
|
36
|
+
variantTypeIds: Set<VariantTypeId>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Expose aggregate sample container for convenience
|
|
41
|
+
*/
|
|
42
|
+
export type SampleContainer = {
|
|
43
|
+
item: Item<Sample>;
|
|
44
|
+
paternalSample: Item<Sample> | null;
|
|
45
|
+
maternalSample: Item<Sample> | null;
|
|
46
|
+
phenotypes: PhenotypicFeature[];
|
|
47
|
+
otherPedigreeSamples: Item<Sample>[];
|
|
48
|
+
variantTypeIds: Set<VariantTypeId>;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// lazy import MockApiClient to ensure that it is excluded from the build artifact
|
|
52
|
+
const api = import.meta.env.PROD
|
|
53
|
+
? new WindowApiClient()
|
|
54
|
+
: await (async () => {
|
|
55
|
+
const module = await import("../mocks/MockApiClient.ts");
|
|
56
|
+
return new module.MockApiClient();
|
|
57
|
+
})();
|
|
58
|
+
|
|
59
|
+
export async function fetchConfig(): Promise<ConfigJson> {
|
|
60
|
+
console.log("Api.fetchConfig");
|
|
61
|
+
const config: Json = await api.getConfig();
|
|
62
|
+
if (config === null) throw new RuntimeError("no config provided");
|
|
63
|
+
return validateConfig(config);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function fetchDecisionTree(): Promise<DecisionTree | null> {
|
|
67
|
+
console.log("Api.fetchDecisionTree");
|
|
68
|
+
return await api.getDecisionTree();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function fetchSampleTree(): Promise<DecisionTree | null> {
|
|
72
|
+
console.log("Api.fetchSampleTree");
|
|
73
|
+
return await api.getSampleTree();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function fetchSamples(params: Params): Promise<PagedItems<SampleContainer>> {
|
|
77
|
+
console.log("Api.fetchSamples", JSON.stringify(params));
|
|
78
|
+
const samplePagedItems = await api.getSamples(params);
|
|
79
|
+
const samples = await Promise.all(samplePagedItems.items.map((sample) => fetchSampleContainer(sample)));
|
|
80
|
+
return {
|
|
81
|
+
page: samplePagedItems.page,
|
|
82
|
+
total: samplePagedItems.total,
|
|
83
|
+
items: samples.map((sample) => ({ id: sample.item.id, data: sample })),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Fetch metadata composed of app metadata, high throughput sequencing file metadata and records metadata
|
|
89
|
+
*/
|
|
90
|
+
export async function fetchMetadata(): Promise<MetadataContainer> {
|
|
91
|
+
console.log("Api.fetchMetadata");
|
|
92
|
+
const [appMetadata, htsFileMetadata, recordsMetadata, variantTypeIds] = await Promise.all([
|
|
93
|
+
api.getAppMetadata(),
|
|
94
|
+
api.getHtsFileMetadata(),
|
|
95
|
+
api.getRecordsMeta(),
|
|
96
|
+
fetchVariantTypeIdsQuery(),
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
// precompute field map
|
|
100
|
+
const fieldMap = createFieldMap(recordsMetadata);
|
|
101
|
+
|
|
102
|
+
return { app: appMetadata, htsFile: htsFileMetadata, records: { ...recordsMetadata, fieldMap }, variantTypeIds };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Fetch sample composed of sample, pedigree samples and phenotypic features
|
|
107
|
+
*/
|
|
108
|
+
export async function fetchSampleById(sampleId: number): Promise<SampleContainer> {
|
|
109
|
+
console.log("Api.fetchSampleById", sampleId);
|
|
110
|
+
const sample = await api.getSampleById(sampleId);
|
|
111
|
+
|
|
112
|
+
const [pedigreeSamples, phenotypicFeatures, variantTypeIds] = await Promise.all([
|
|
113
|
+
fetchPedigreeSamples(sample),
|
|
114
|
+
fetchPhenotypicFeatures(sample),
|
|
115
|
+
fetchVariantTypeIdsQuery(),
|
|
116
|
+
]);
|
|
117
|
+
|
|
118
|
+
return composeSample(sample, phenotypicFeatures, pedigreeSamples, variantTypeIds);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function fetchRecordById(id: number): Promise<Item<VcfRecord>> {
|
|
122
|
+
console.log("Api.fetchRecordById", id);
|
|
123
|
+
return api.getRecordById(id);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export async function fetchRecords(params: Params): Promise<PagedItems<VcfRecord>> {
|
|
127
|
+
console.log("Api.fetchRecords", JSON.stringify(params));
|
|
128
|
+
const [recordsMeta, records] = await Promise.all([api.getRecordsMeta(), api.getRecords(params)]);
|
|
129
|
+
if (recordsMeta.info.CSQ === undefined) {
|
|
130
|
+
return records;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const orders = createRecordSort(recordsMeta, params.sort).orders.filter(
|
|
134
|
+
(order) =>
|
|
135
|
+
order.field.parent?.id === "CSQ" &&
|
|
136
|
+
isNumerical(order.field) &&
|
|
137
|
+
order.field.number.type === "NUMBER" &&
|
|
138
|
+
order.field.number.count === 1,
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const fieldMetas = (recordsMeta.info.CSQ.nested as NestedFieldMetadata).items;
|
|
142
|
+
const consequenceIndex = fieldMetas.findIndex((item) => item.id === "Consequence");
|
|
143
|
+
const pickIndex = fieldMetas.findIndex((item) => item.id === "PICK");
|
|
144
|
+
|
|
145
|
+
for (const record of records.items) {
|
|
146
|
+
const csqArray = record.data.n.CSQ as Value[][] | undefined;
|
|
147
|
+
if (csqArray) {
|
|
148
|
+
csqArray.sort((aValue, bValue) => {
|
|
149
|
+
for (const order of orders) {
|
|
150
|
+
const compareValue = compareCsq(aValue, bValue, order.field, order.direction);
|
|
151
|
+
if (compareValue !== 0) return compareValue;
|
|
152
|
+
}
|
|
153
|
+
return compareCsqDefault(aValue, bValue, pickIndex, consequenceIndex);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return records;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export async function fetchSampleProbandIds(): Promise<number[]> {
|
|
161
|
+
console.log("Api.fetchSampleProbandIds");
|
|
162
|
+
const query: Query = { selector: ["proband"], operator: "==", args: true };
|
|
163
|
+
const samplePagedItems = await api.getSamples({ query, page: 0, size: Number.MAX_SAFE_INTEGER });
|
|
164
|
+
return samplePagedItems.items.map((sampleItem) => sampleItem.id);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export async function fetchFastaGz(contig: string, pos: number): Promise<Uint8Array | null> {
|
|
168
|
+
console.log("Api.fetchFastaGz", contig, pos);
|
|
169
|
+
return api.getFastaGz(contig, pos);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export async function fetchGenesGz(): Promise<Uint8Array | null> {
|
|
173
|
+
console.log("Api.fetchGenesGz");
|
|
174
|
+
return api.getGenesGz();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export async function fetchCram(sampleId: string): Promise<Cram | null> {
|
|
178
|
+
console.log("Api.fetchCram", sampleId);
|
|
179
|
+
return api.getCram(sampleId);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async function fetchSampleContainer(sample: Item<Sample>): Promise<SampleContainer> {
|
|
183
|
+
const [pedigreeSamples, phenotypicFeatures, variantTypeIds] = await Promise.all([
|
|
184
|
+
fetchPedigreeSamples(sample),
|
|
185
|
+
fetchPhenotypicFeatures(sample),
|
|
186
|
+
fetchVariantTypeIdsQuery(),
|
|
187
|
+
]);
|
|
188
|
+
|
|
189
|
+
return composeSample(sample, phenotypicFeatures, pedigreeSamples, variantTypeIds);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Compose sample from API sample, API sample phenotypes and API pedigree samples data
|
|
194
|
+
*
|
|
195
|
+
* @param sample API sample
|
|
196
|
+
* @param samplePhenotypes API sample phenotypes
|
|
197
|
+
* @param pedigreeSamples API samples from same pedigree
|
|
198
|
+
* @param variantTypeIds variant types available for this sample
|
|
199
|
+
*/
|
|
200
|
+
export function composeSample(
|
|
201
|
+
sample: Item<Sample>,
|
|
202
|
+
samplePhenotypes?: PhenotypicFeature[],
|
|
203
|
+
pedigreeSamples?: PagedItems<Sample>,
|
|
204
|
+
variantTypeIds?: Set<VariantTypeId>,
|
|
205
|
+
): SampleContainer {
|
|
206
|
+
let paternalSample: Item<Sample> | null = null;
|
|
207
|
+
let maternalSample: Item<Sample> | null = null;
|
|
208
|
+
const otherPedigreeSamples: Item<Sample>[] = [];
|
|
209
|
+
|
|
210
|
+
pedigreeSamples?.items.forEach((pedigreeSample) => {
|
|
211
|
+
if (isSampleFather(sample.data, pedigreeSample.data)) {
|
|
212
|
+
paternalSample = pedigreeSample;
|
|
213
|
+
} else if (isSampleMother(sample.data, pedigreeSample.data)) {
|
|
214
|
+
maternalSample = pedigreeSample;
|
|
215
|
+
} else {
|
|
216
|
+
otherPedigreeSamples.push(pedigreeSample);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
item: sample,
|
|
222
|
+
paternalSample,
|
|
223
|
+
maternalSample,
|
|
224
|
+
phenotypes: samplePhenotypes || [],
|
|
225
|
+
otherPedigreeSamples,
|
|
226
|
+
variantTypeIds: variantTypeIds || new Set<VariantTypeId>(),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async function fetchPedigreeSamples(sample: Item<Sample>): Promise<PagedItems<Sample>> {
|
|
231
|
+
return await api.getSamples({
|
|
232
|
+
query: {
|
|
233
|
+
operator: "and",
|
|
234
|
+
args: [
|
|
235
|
+
{ selector: ["person", "individualId"], operator: "!=", args: sample.data.person.individualId },
|
|
236
|
+
{ selector: ["person", "familyId"], operator: "==", args: sample.data.person.familyId },
|
|
237
|
+
],
|
|
238
|
+
},
|
|
239
|
+
size: Number.MAX_SAFE_INTEGER,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async function fetchPhenotypicFeatures(sample: Item<Sample>): Promise<PhenotypicFeature[]> {
|
|
244
|
+
const phenotypes = await api.getPhenotypes({
|
|
245
|
+
query: { selector: ["subject", "id"], operator: "==", args: sample.data.person.individualId },
|
|
246
|
+
size: Number.MAX_SAFE_INTEGER,
|
|
247
|
+
});
|
|
248
|
+
return phenotypes.items.map((item) => item.data).flatMap((phenotype) => phenotype.phenotypicFeaturesList);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function fetchVariantTypeIdsQuery(): Promise<Set<VariantTypeId>> {
|
|
252
|
+
const config: ConfigJson = await fetchConfig();
|
|
253
|
+
|
|
254
|
+
const variantTypeIds = new Set<VariantTypeId>();
|
|
255
|
+
const params = config.vip.params.cram;
|
|
256
|
+
if (params) {
|
|
257
|
+
if (params.call_snv) variantTypeIds.add("snv");
|
|
258
|
+
if (params.call_str) variantTypeIds.add("str");
|
|
259
|
+
if (params.call_sv || params.call_cnv) variantTypeIds.add("sv");
|
|
260
|
+
} else {
|
|
261
|
+
variantTypeIds.add("snv");
|
|
262
|
+
variantTypeIds.add("str");
|
|
263
|
+
variantTypeIds.add("sv");
|
|
264
|
+
}
|
|
265
|
+
return variantTypeIds;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// development
|
|
269
|
+
export function isDatasetSupport(): boolean {
|
|
270
|
+
return !import.meta.env.PROD;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export function getDatasetIds(): string[] {
|
|
274
|
+
if (import.meta.env.PROD) throw new Error("unsupported");
|
|
275
|
+
return (api as MockApiClient).getDatasetIds();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function selectDataset(id: string): void {
|
|
279
|
+
if (import.meta.env.PROD) throw new Error(`unknown id ${id}`);
|
|
280
|
+
(api as MockApiClient).selectDataset(id);
|
|
281
|
+
}
|