Skip to content

Commit

Permalink
feature: improve record details presentation
Browse files Browse the repository at this point in the history
  • Loading branch information
dennishendriksen committed Jun 22, 2020
1 parent e7a1b0b commit df68023
Show file tree
Hide file tree
Showing 11 changed files with 357 additions and 49 deletions.
8 changes: 8 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
font-size: .75rem;
}

td {
white-space: nowrap
}

td.compact {
padding: 0;
width: 0;
Expand All @@ -61,4 +65,8 @@
.nuc-g {
background-color: #ffec8b;
}

.modal-container {
overflow: auto
}
</style>
25 changes: 25 additions & 0 deletions src/components/Bases.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<template>
<span>
<span v-for="(base, index) in bases.split('')" :key="index"
:class="getBaseClass(base)">{{ base }}</span>
</span>
</template>

<script lang="ts">
// eslint-disable-next-line no-unused-vars
import Vue, {PropType} from 'vue'
export default Vue.extend({
props: {
bases: String
},
methods: {
getBaseClass(base: string): object {
const classes: object = {nuc: true}
// @ts-ignore
classes['nuc-' + base.toLocaleLowerCase()] = true
return classes
}
}
})
</script>
23 changes: 23 additions & 0 deletions src/components/Identifiers.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template>
<div>
<span v-for="(id, index) in identifiers" :key="id">
<a v-if="id.startsWith('rs')" :href="'https://www.ncbi.nlm.nih.gov/snp/' + encodeURIComponent(id)" target="_blank">
{{ id }}
<b-icon-box-arrow-in-up-right class="ml-1"/>
</a>
<span v-else>{{ id }}</span>
<span v-if="index < identifiers.length - 1">, </span>
</span>
</div>
</template>

<script lang="ts">
// eslint-disable-next-line no-unused-vars
import Vue, {PropType} from 'vue'
export default Vue.extend({
props: {
identifiers: Array as PropType<string[]>
}
})
</script>
108 changes: 108 additions & 0 deletions src/components/RecordDetails.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<template>
<div>
<b-table
small
responsive=true
:fields="fields"
:items="items">
<template v-slot:head()="data">
{{ data.label ? $t(data.label) : '' }}
</template>
<template v-slot:cell(key)="data">
<span v-if="data.item.key === 'c'">
{{ $t('chr') }}
</span>
<span v-else-if="data.item.key === 'p'">
{{ $t('pos') }}
</span>
<span v-else-if="data.item.key === 'i'">
{{ $t('id') }}
</span>
<span v-else-if="data.item.key === 'r'">
{{ $t('ref') }}
</span>
<span v-else-if="data.item.key === 'a'">
{{ $t('alt') }}
</span>
<span v-else-if="data.item.key === 'q'">
{{ $t('qual') }}
</span>
<span v-else-if="data.item.key === 'f'">
{{ $t('filter') }}
</span>
<span v-else-if="data.item.key === 'n'">
{{ $t('info') }}
</span>
<span v-else-if="data.item.key === 's'">
{{ $t('sample') }}
</span>
</template>
<template v-slot:cell(val)="data">
<span v-if="data.item.key === 'c'">
{{ data.item.val }}
</span>
<span v-else-if="data.item.key === 'p'">
{{ data.item.val }}
</span>
<span v-else-if="data.item.key === 'i'">
<Identifiers :identifiers="data.item.val" />
</span>
<span v-else-if="data.item.key === 'r'">
<Bases :bases="data.item.val" />
</span>
<span v-else-if="data.item.key === 'a'">
<span v-for="(alt, index) in data.item.val" :key="index">
<Bases :bases="alt" />
<span v-if="index < data.item.val.length - 1">, </span>
</span>
</span>
<span v-else-if="data.item.key === 'q'">
{{ data.item.val }}
</span>
<span v-else-if="data.item.key === 'f'">
{{ data.item.val }}
</span>
<span v-else-if="data.item.key === 'n'">
<RecordInfoDetails :metadata="metadata.info" :info="data.item.val" />
</span>
<span v-else-if="data.item.key === 's'">
{{ data.item.val }}
</span>
</template>
</b-table>
</div>
</template>

<script lang="ts">
// eslint-disable-next-line no-unused-vars
import Vue, {PropType} from 'vue'
// eslint-disable-next-line no-unused-vars
import {Record, RecordsMetadata, Sample} from '@molgenis/vip-report-api'
import Bases from '@/components/Bases.vue'
import Identifiers from '@/components/Identifiers.vue'
import RecordInfoDetails from '@/components/RecordInfoDetails.vue'
export default Vue.extend({
components: {Bases, Identifiers, RecordInfoDetails},
props: {
metadata: Object as PropType<RecordsMetadata>,
record: Object as PropType<Record>,
sample: Object as PropType<Sample>
},
computed: {
fields: function () {
return [
{key: 'key', label: 'prop'},
{key: 'val', label: 'value'}]
},
items() {
const items = []
for (let key in this.record) {
const item = {key: key, val: this.record[key]}
items.push(item)
}
return items
}
}
})
</script>
64 changes: 64 additions & 0 deletions src/components/RecordInfoDetails.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<template>
<div>
<b-table
small
responsive=true
:fields="fields"
:items="items">
<template v-slot:head()="data">
{{ $t(data.label) }}
</template>
<template v-slot:cell(key)="data">
<!-- todo: show description in addition to key: {{ getInfoMetadata(data.item.key).description }} -->
{{ data.item.key }}
</template>
<template v-slot:cell(val)="data">
<RecordInfoDetailsItem :metadata="getInfoMetadata(data.item.key)" :value="data.item.val"/>
</template>
</b-table>
</div>
</template>

<script lang="ts">
// eslint-disable-next-line no-unused-vars
import Vue, {PropType} from 'vue'
// eslint-disable-next-line no-unused-vars
import {InfoMetadata} from '@molgenis/vip-report-api'
import RecordInfoDetailsItem from '@/components/RecordInfoDetailsItem.vue'
export default Vue.extend({
components: {RecordInfoDetailsItem},
props: {
metadata: Array as PropType<InfoMetadata[]>,
info: Object as PropType<object>
},
computed: {
fields: function () {
return [
{key: 'key', label: 'prop'},
{key: 'val', label: 'value'}]
},
items() {
const items = []
for (let key in this.info) {
// fix for invalid VCF
if (key !== '') {
// @ts-ignore
const item = {key: key, val: this.info[key]}
items.push(item)
}
}
return items
}
},
methods: {
getInfoMetadata(key: string): InfoMetadata {
const infoMetadata = this.metadata.find(item => item.id === key)
if (infoMetadata === undefined) {
throw new Error('missing info metadata for \'' + key + '\'')
}
return infoMetadata
}
}
})
</script>
41 changes: 41 additions & 0 deletions src/components/RecordInfoDetailsItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<div>
<span v-if="metadata.number === undefined">
{{ value }}
</span>
<span v-else-if="metadata.number && metadata.number.type === 'NUMBER' && metadata.number.count === 1">
<span v-if="metadata.type === 'NESTED'">
<RecordInfoNestedDetails :metadata="metadata.nested" :info="[value]"/>
</span>
<span v-else>
{{ value }}
</span>
</span>
<span v-else>
<span v-if="metadata.type === 'NESTED'">
<RecordInfoNestedDetails :metadata="metadata.nested" :info="value"/>
</span>
<span v-else>
<span v-for="(item, index) in value" :key="index">
{{ item }}<span v-if="index < value.length - 1">, </span>
</span>
</span>
</span>
</div>
</template>

<script lang="ts">
// eslint-disable-next-line no-unused-vars
import Vue, {PropType} from 'vue'
// eslint-disable-next-line no-unused-vars
import {InfoMetadata} from '@molgenis/vip-report-api'
import RecordInfoNestedDetails from '@/components/RecordInfoNestedDetails.vue'
export default Vue.extend({
components: {RecordInfoNestedDetails},
props: {
metadata: Object as PropType<InfoMetadata>,
value: [String, Number, Boolean, Array, Object] as PropType<string | number | boolean | object | string[] | number[] | boolean[] | object[]>
}
})
</script>
62 changes: 62 additions & 0 deletions src/components/RecordInfoNestedDetails.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<div>
<b-table
small
:fields="fields"
:items="items">
<template v-slot:head()="data">
{{ $t(data.label) }}
</template>
<template v-slot:cell()="data">
<span v-if="data.field.metadata.number === undefined">
{{ data.item[data.field.index] }}
</span>
<span v-else-if="data.field.metadata.number && data.field.metadata.number.type === 'NUMBER' && data.field.metadata.number.count === 1">
{{ data.item[data.field.index] }}
</span>
<span v-else>
<span v-for="(item, index) in data.item[data.field.index]" :key="index">
{{ item }}<span v-if="index < data.item[data.field.index].length - 1">, </span>
</span>
</span>
</template>
</b-table>
</div>
</template>

<script lang="ts">
// eslint-disable-next-line no-unused-vars
import Vue, {PropType} from 'vue'
// eslint-disable-next-line no-unused-vars
import {InfoMetadata} from '@molgenis/vip-report-api'
export default Vue.extend({
props: {
metadata: Array as PropType<InfoMetadata[]>,
info: Array as PropType<object[]>
},
computed: {
fields: function () {
const fields = []
let index = 0
for (const info of this.metadata) {
fields.push({key: info.id, label: info.description, index: index, metadata: info})
++index
}
return fields
},
items() {
return this.info
}
},
methods: {
getInfoMetadata(key: string): InfoMetadata {
const infoMetadata = this.metadata.find(item => item.id === key)
if (infoMetadata === undefined) {
throw new Error('missing info metadata for \'' + key + '\'')
}
return infoMetadata
}
}
})
</script>
Loading

0 comments on commit df68023

Please sign in to comment.