Skip to content

Commit 22ce49c

Browse files
authored
Merge pull request #566 from VariantEffect/release-2025.5.0
Release 2025.5.0
2 parents 2fe0807 + 58c4744 commit 22ce49c

37 files changed

+14793
-4505
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,8 @@ venv.bak/
132132
# Sphinx documentation build cache
133133
.doctrees/
134134

135+
# IDEs and editors
136+
.vscode/
137+
135138
# OS X folder view option files
136139
*.DS_Store

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mavedb-ui",
3-
"version": "2025.4.5",
3+
"version": "2025.5.0",
44
"private": true,
55
"type": "module",
66
"scripts": {

src/assets/layout.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
}
5151

5252
.mavedb-screen-title-controls .p-button {
53-
margin-right: 10px;
53+
margin-right: 0.25rem;
5454
}
5555

5656
.mavedb-screen-title-controls .p-button:last-child {

src/components/AssayFactSheet.vue

Lines changed: 155 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<div class="mavedb-assay-facts-label">Assay Type</div>
2323
<div class="mavedb-assay-facts-value">
2424
<div v-if="scoreSet.experiment.keywords?.some((k) => k.keyword.key === 'Phenotypic Assay Method')">
25-
{{ scoreSet.experiment.keywords.find((k) => k.keyword.key === 'Phenotypic Assay Method').keyword.label }}
25+
{{ scoreSet.experiment.keywords.find((k) => k.keyword.key === 'Phenotypic Assay Method')?.keyword.label }}
2626
</div>
2727
<div v-else>Not specified</div>
2828
</div>
@@ -32,7 +32,7 @@
3232
<div class="mavedb-assay-facts-value">
3333
<div v-if="scoreSet.experiment.keywords?.some((k) => k.keyword.key === 'Molecular Mechanism Assessed')">
3434
{{
35-
scoreSet.experiment.keywords.find((k) => k.keyword.key === 'Molecular Mechanism Assessed').keyword.label
35+
scoreSet.experiment.keywords.find((k) => k.keyword.key === 'Molecular Mechanism Assessed')?.keyword.label
3636
}}
3737
</div>
3838
<div v-else>Not specified</div>
@@ -42,7 +42,9 @@
4242
<div class="mavedb-assay-facts-label">Variant Consequences Detected</div>
4343
<div class="mavedb-assay-facts-value">
4444
<div v-if="scoreSet.experiment.keywords?.some((k) => k.keyword.key === 'Phenotypic Assay Mechanism')">
45-
{{ scoreSet.experiment.keywords.find((k) => k.keyword.key === 'Phenotypic Assay Mechanism').keyword.label }}
45+
{{
46+
scoreSet.experiment.keywords.find((k) => k.keyword.key === 'Phenotypic Assay Mechanism')?.keyword.label
47+
}}
4648
</div>
4749
<div v-else>Not specified</div>
4850
</div>
@@ -52,7 +54,7 @@
5254
<div class="mavedb-assay-facts-value">
5355
<div v-if="scoreSet.experiment.keywords?.some((k) => k.keyword.key === 'Phenotypic Assay Model System')">
5456
{{
55-
scoreSet.experiment.keywords.find((k) => k.keyword.key === 'Phenotypic Assay Model System').keyword.label
57+
scoreSet.experiment.keywords.find((k) => k.keyword.key === 'Phenotypic Assay Model System')?.keyword.label
5658
}}
5759
</div>
5860
<div v-else>Not specified</div>
@@ -77,48 +79,66 @@
7779
</div>
7880
</div>
7981
</div>
80-
<div class="mavedb-assay-facts-section-title">Clinical Performance</div>
82+
<div class="mavedb-assay-facts-section-title">
83+
Clinical Performance<sup v-if="!primaryScoreRangeIsInvestigatorProvided">*</sup>
84+
</div>
8185
<div class="mavedb-assay-facts-section">
82-
<div v-if="scoreSet.scoreRanges?.investigatorProvided?.ranges[0]?.oddsPath?.ratio">
86+
<div v-if="primaryScoreRange?.functionalRanges?.some((r) => r.oddspathsRatio)">
8387
<div class="mavedb-assay-facts-row">
8488
<div class="mavedb-assay-facts-label">OddsPath – Normal</div>
8589
<div
86-
v-if="scoreSet.scoreRanges?.investigatorProvided?.ranges?.some((r) => r.classification === 'normal')"
90+
v-if="primaryScoreRange?.functionalRanges?.some((r) => r.classification === 'normal' && r.oddspathsRatio)"
8791
class="mavedb-assay-facts-value"
8892
>
89-
{{
90-
roundOddsPath(
91-
scoreSet.scoreRanges.investigatorProvided.ranges.find((r) => r.classification === 'normal').oddsPath
92-
?.ratio
93-
)
94-
}}
95-
<span class="mavedb-classification-badge mavedb-blue">
96-
{{
97-
scoreSet.scoreRanges.investigatorProvided.ranges.find((r) => r.classification === 'normal').oddsPath
98-
?.evidence
99-
}}
93+
{{ roundOddsPath(normalScoreRange?.oddspathsRatio) }}
94+
<span
95+
:class="[
96+
'mavedb-classification-badge',
97+
`mave-evidence-code-${
98+
normalScoreRange?.acmgClassification
99+
? formatEvidenceCodeForScoreRange(normalScoreRange)
100+
: 'INDETERMINATE'
101+
}`
102+
]"
103+
>
104+
{{ formatEvidenceCodeForScoreRange(normalScoreRange) }}
100105
</span>
101106
</div>
107+
<div v-else class="mavedb-assay-facts-value">OddsPath normal not provided</div>
102108
</div>
103109
<div class="mavedb-assay-facts-row">
104110
<div class="mavedb-assay-facts-label">OddsPath – Abnormal</div>
105111
<div
106-
v-if="scoreSet.scoreRanges?.investigatorProvided?.ranges?.some((r) => r.classification === 'abnormal')"
112+
v-if="primaryScoreRange?.functionalRanges?.some((r) => r.classification === 'abnormal' && r.oddspathsRatio)"
107113
class="mavedb-assay-facts-value"
108114
>
109-
{{
110-
roundOddsPath(
111-
scoreSet.scoreRanges.investigatorProvided.ranges.find((r) => r.classification === 'abnormal').oddsPath
112-
?.ratio
113-
)
114-
}}
115-
<span class="mavedb-classification-badge mavedb-red strong">
116-
{{
117-
scoreSet.scoreRanges.investigatorProvided.ranges.find((r) => r.classification === 'abnormal').oddsPath
118-
?.evidence
119-
}}
115+
{{ roundOddsPath(abnormalScoreRange?.oddspathsRatio) }}
116+
<span
117+
:class="[
118+
'mavedb-classification-badge',
119+
`mave-evidence-code-${
120+
abnormalScoreRange?.acmgClassification
121+
? formatEvidenceCodeForScoreRange(abnormalScoreRange)
122+
: 'INDETERMINATE'
123+
}`
124+
]"
125+
>
126+
{{ formatEvidenceCodeForScoreRange(abnormalScoreRange) }}
120127
</span>
121128
</div>
129+
<div v-else class="mavedb-assay-facts-value">OddsPath abnormal not provided</div>
130+
</div>
131+
<div v-if="!primaryScoreRangeIsInvestigatorProvided" style="font-size: 10px; margin-top: 4px">
132+
<sup>*</sup>OddsPath data from non-primary source(s):
133+
<template v-if="oddsPathSources">
134+
(
135+
<template v-for="(s, i) in oddsPathSources" :key="s.url">
136+
<a :href="s.url" rel="noopener" target="_blank">{{ shortCitationForPublication(s) }}</a
137+
><span v-if="i < oddsPathSources.length - 1">, </span>
138+
</template>
139+
).
140+
</template>
141+
<template v-else>.</template>
122142
</div>
123143
</div>
124144
<div v-else>OddsPath values are not provided for this score set.</div>
@@ -131,6 +151,7 @@ import _ from 'lodash'
131151
import {defineComponent, PropType} from 'vue'
132152
133153
import {getScoreSetFirstAuthor} from '@/lib/score-sets'
154+
import {shortCitationForPublication} from '@/lib/publication'
134155
import type {components} from '@/schema/openapi'
135156
136157
export default defineComponent({
@@ -143,6 +164,12 @@ export default defineComponent({
143164
}
144165
},
145166
167+
setup() {
168+
return {
169+
shortCitationForPublication
170+
}
171+
},
172+
146173
computed: {
147174
firstAuthor: function () {
148175
const firstAuthor = getScoreSetFirstAuthor(this.scoreSet)
@@ -204,12 +231,51 @@ export default defineComponent({
204231
default:
205232
return null
206233
}
234+
},
235+
primaryScoreRange: function () {
236+
if (this.scoreSet.scoreCalibrations == null) {
237+
return null
238+
}
239+
240+
return (
241+
Object.values(this.scoreSet.scoreCalibrations).filter((sr) => sr?.primary)[0] ||
242+
this.scoreSet.scoreCalibrations?.find((sr) => sr?.investigatorProvided) ||
243+
null
244+
)
245+
},
246+
primaryScoreRangeIsInvestigatorProvided: function () {
247+
if (this.scoreSet.scoreCalibrations == null) {
248+
return false
249+
}
250+
251+
return this.primaryScoreRange === this.scoreSet.scoreCalibrations?.find((sr) => sr?.investigatorProvided)
252+
},
253+
abnormalScoreRange: function () {
254+
return this.primaryScoreRange?.functionalRanges?.find((r) => r.classification === 'abnormal') || null
255+
},
256+
normalScoreRange: function () {
257+
return this.primaryScoreRange?.functionalRanges?.find((r) => r.classification === 'normal') || null
258+
},
259+
oddsPathSources() {
260+
return this.primaryScoreRange?.classificationSources
261+
},
262+
sources: function () {
263+
return this.scoreSet.primaryPublicationIdentifiers.concat(this.scoreSet.secondaryPublicationIdentifiers)
207264
}
208265
},
209266
210267
methods: {
211-
roundOddsPath: function (oddsPath: number | undefined) {
212-
return oddsPath?.toPrecision(5)
268+
roundOddsPath: function (oddsPath: number | null | undefined) {
269+
return oddsPath?.toFixed(3)
270+
},
271+
formatEvidenceCodeForScoreRange: function (functionalRange: components['schemas']['FunctionalRange'] | null) {
272+
if (!functionalRange?.acmgClassification?.evidenceStrength) {
273+
return ''
274+
}
275+
276+
const criterion = functionalRange.acmgClassification.criterion
277+
const strength = functionalRange.acmgClassification.evidenceStrength.toUpperCase()
278+
return `${criterion}_${strength}`
213279
}
214280
}
215281
})
@@ -308,4 +374,61 @@ export default defineComponent({
308374
background: #991b1b;
309375
color: white;
310376
}
377+
378+
/* Evidence Strengths */
379+
380+
.mave-evidence-code-PS3_VERY_STRONG {
381+
background-color: #943744;
382+
font-weight: bold;
383+
}
384+
385+
.mave-evidence-code-PS3_STRONG {
386+
background-color: #b85c6b;
387+
font-weight: bold;
388+
}
389+
390+
.mave-evidence-code-PS3_MODERATE_PLUS {
391+
background-color: #ca7682;
392+
font-weight: bold;
393+
}
394+
395+
.mave-evidence-code-PS3_MODERATE {
396+
background-color: #d68f99;
397+
font-weight: bold;
398+
}
399+
400+
.mave-evidence-code-PS3_SUPPORTING {
401+
background-color: #e6b1b8;
402+
font-weight: bold;
403+
}
404+
405+
.mave-evidence-code-BS3_SUPPORTING {
406+
background-color: #e4f1f6;
407+
font-weight: bold;
408+
}
409+
410+
.mave-evidence-code-BS3_MODERATE {
411+
background-color: #d0e8f0;
412+
font-weight: bold;
413+
}
414+
415+
.mave-evidence-code-BS3_MODERATE_PLUS {
416+
background-color: #99c8dc;
417+
font-weight: bold;
418+
}
419+
420+
.mave-evidence-code-BS3_STRONG {
421+
background-color: #7ab5d1;
422+
font-weight: bold;
423+
}
424+
425+
.mave-evidence-code-BS3_VERY_STRONG {
426+
background-color: #4b91a6;
427+
font-weight: bold;
428+
}
429+
430+
.mave-evidence-code-INDETERMINATE {
431+
background-color: #e0e0e0;
432+
font-weight: bold;
433+
}
311434
</style>

0 commit comments

Comments
 (0)