Skip to content

Commit

Permalink
feat: seqvar item modified & revert (#1818)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregoor authored Jul 20, 2024
1 parent 06a7dd0 commit c885421
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 70 deletions.
10 changes: 10 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@iconify-json/fa-regular": "^1.1.8",
"@iconify-json/fa-solid": "^1.1.8",
"@iconify-json/fa6-solid": "^1.1.21",
"@iconify-json/fluent": "^1.1.59",
"@iconify-json/mdi": "^1.1.66",
"@iconify-json/medical-icon": "^1.1.8",
"@iconify-json/oi": "^1.1.8",
Expand Down
1 change: 0 additions & 1 deletion frontend/src/cases/components/CaseDetailApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ const caseAnalysisStore = useCaseAnalysisStore()
const seqvarsQueryStore = useSeqvarsQueryStore()
// Routing-related.
const router = useRouter()
const refreshStores = async () => {
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/cases/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import StrucvarDetails from '@/svs/views/StrucvarDetails/StrucvarDetails.vue'
import SvFilterApp from '@/svs/components/SvFilterApp.vue'
import { useHistoryStore } from '@/varfish/stores/history'
import FilterApp from '@/variants/components/FilterApp.vue'
import SeqvarsApp from '@/seqvars/App.vue'
import SeqvarDetails from '@/variants/views/SeqvarDetails/SeqvarDetails.vue'
import {
RouteLocationNormalized,
Expand Down Expand Up @@ -92,6 +93,14 @@ const routes: RouteRecordRaw[] = [
caseUuid: route.params.case,
}),
},
{
name: 'seqvars',
path: '/seqvars/:case',
component: SeqvarsApp,
props: (route: RouteLocationNormalized) => ({
caseUuid: route.params.case,
}),
},
{
name: 'seqvar-details',
path: '/seqvar/details/:row/:selectedSection?',
Expand Down
65 changes: 65 additions & 0 deletions frontend/src/seqvars/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<script lang="ts" setup>
import { onMounted, watch } from 'vue'
import SeqvarsFiltration from './views/SeqvarsFiltration.vue'
import { useCaseAnalysisStore } from './stores/caseAnalysis'
import { useSeqvarPresetsStore } from './stores/presets'
import { useSeqvarsQueryStore } from './stores/query'
import { computed } from 'vue'
const appContext = JSON.parse(
document
.getElementById('sodar-ss-app-context')!
.getAttribute('app-context') || '{}',
)
const props = defineProps<{ caseUuid: string }>()
const seqvarPresetsStore = useSeqvarPresetsStore()
const caseAnalysisStore = useCaseAnalysisStore()
const seqvarsQueryStore = useSeqvarsQueryStore()
const refreshStores = async () => {
if (
appContext?.csrf_token &&
appContext?.project?.sodar_uuid &&
props?.caseUuid
) {
await Promise.all([
(async () => {
await Promise.all([
seqvarPresetsStore.initialize(appContext.project.sodar_uuid),
caseAnalysisStore.initialize(
appContext.project.sodar_uuid,
props.caseUuid,
),
])
await seqvarsQueryStore.initialize(
appContext.project.sodar_uuid,
props.caseUuid,
caseAnalysisStore.currentAnalysis!.sodar_uuid,
caseAnalysisStore.currentSession!.sodar_uuid,
seqvarPresetsStore.presetSets.values().next().value.sodar_uuid,
)
})(),
])
}
}
onMounted(() => {
refreshStores()
})
watch(
() => props.caseUuid,
() => refreshStores(),
)
const presets = computed(() =>
[...seqvarPresetsStore.presetSetVersions.values()].at(0),
)
</script>

<template>
<SeqvarsFiltration v-if="presets" :presets="presets" />
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { SeqvarsQueryPresetsFrequency } from '@varfish-org/varfish-api/lib'
import CollapsibleGroup from '@/seqvars/components/CollapsibleGroup.vue'
import Hr from '@/seqvars/components/Hr.vue'
import Item from '@/seqvars/components/Item.vue'
import ModifiedIcon from '@/seqvars/components/ModifiedIcon.vue'
import { Query } from '@/seqvars/types'
import { copy } from '@/varfish/helpers'
Expand All @@ -15,6 +14,10 @@ const { presets } = defineProps<{ presets: SeqvarsQueryPresetsFrequency[] }>()
const model = defineModel<Query>({
required: true,
})
const setToPreset = (preset: SeqvarsQueryPresetsFrequency) => {
model.value.frequencypresets = preset.sodar_uuid
model.value.frequency = copy(preset)
}
</script>

<template>
Expand All @@ -28,21 +31,12 @@ const model = defineModel<Query>({
v-for="preset in presets"
:key="preset.sodar_uuid"
:selected="preset.sodar_uuid === model.frequencypresets"
@click="
() => {
model.frequencypresets = preset.sodar_uuid
model.frequency = copy(preset)
}
"
:modified="!matchesFrequencyPreset(model.frequency, preset)"
@click="() => setToPreset(preset)"
@revert="() => setToPreset(preset)"
>
<template #default>{{ preset.label }}</template>
<template #extra>
<ModifiedIcon
v-if="
preset.sodar_uuid === model.frequencypresets &&
!matchesFrequencyPreset(model.frequency, preset)
" /></template
></Item>
{{ preset.label }}
</Item>
</div>

<Hr />
Expand Down
41 changes: 20 additions & 21 deletions frontend/src/seqvars/components/GenotypeSelect/GenotypeSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { copy } from '@/varfish/helpers'
import CollapsibleGroup from '@/seqvars/components/CollapsibleGroup.vue'
import Hr from '@/seqvars/components/Hr.vue'
import Item from '@/seqvars/components/Item.vue'
import ModifiedIcon from '@/seqvars/components/ModifiedIcon.vue'
import { Query } from '@/seqvars/types'
import { Affected, GENOTYPE_PRESETS, SexAssignedAtBirth } from './constants'
Expand All @@ -34,6 +33,11 @@ const recessiveMode = computed<RecessiveModeEnum>({
model.value.genotype.recessive_mode = value
},
})
const setToPreset = (key: SeqvarsGenotypePresetChoice) => {
model.value.genotype = copy(getGenotypeSettingsFromPreset(key))
model.value.genotypepresets = { choice: key }
}
</script>

<template>
Expand All @@ -44,28 +48,18 @@ const recessiveMode = computed<RecessiveModeEnum>({
style="width: 100%; display: flex; flex-direction: column"
>
<Item
v-for="key in Object.keys(GENOTYPE_PRESETS)"
v-for="key in Object.keys(
GENOTYPE_PRESETS,
) as SeqvarsGenotypePresetChoice[]"
:key="key"
:selected="model.genotypepresets?.choice == key"
@click="
() => {
const presetKey = key as SeqvarsGenotypePresetChoice
model.genotype = copy(getGenotypeSettingsFromPreset(presetKey))
model.genotypepresets = { choice: presetKey }
}
"
:modified="!matchesGenotypePreset(model.genotype, key)"
@click="() => setToPreset(key)"
@revert="() => setToPreset(key)"
>
<template #default>{{
key == 'ANY' ? 'any mode' : key.toLowerCase().split('_').join(' ')
}}</template>
<template #extra>
<ModifiedIcon
v-if="
model.genotypepresets?.choice == key &&
!matchesGenotypePreset(model.genotype, key)
"
/>
</template>
{{
key == 'any' ? 'any mode' : key.toLowerCase().split('_').join(' ')
}}
</Item>
</div>

Expand All @@ -91,7 +85,12 @@ const recessiveMode = computed<RecessiveModeEnum>({
:key="index"
style="display: flex; flex-direction: row; align-items: start; gap: 4px"
>
<input :id="choice.sample" type="checkbox" style="margin-top: 6px" />
<input
:id="choice.sample"
v-model="choice.enabled"
type="checkbox"
style="margin-top: 6px"
/>
<div style="display: flex; flex-direction: column">
<label
:for="choice.sample"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ const GENOTYPE_TO_INHERITANCE_MODE = {
hom: [HOM_ALT],
non_hom: [WILD_TYPE, HET_ALT],
variant: [HET_ALT, HOM_ALT],
// TODO: missing
// non_het: [WILD_TYPE, HOM_ALT],
non_het: [WILD_TYPE, HOM_ALT],
} satisfies Record<GenotypeKey, Modes[]>
const modes = computed({
get() {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/seqvars/components/GenotypeSelect/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function getGenotypeSettingsFromPreset(
recessive_mode: preset.recessiveMode,
sample_genotype_choices: (['index', 'father', 'mother'] as Pedigree[]).map(
(sample) => ({
enabled: true,
sample,
genotype: preset.samples[sample],
include_no_call: false,
Expand Down
17 changes: 14 additions & 3 deletions frontend/src/seqvars/components/Item.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
<script setup lang="ts">
const props = withDefaults(defineProps<{ selected?: boolean }>(), {
selected: false,
})
import ItemButton from './ItemButton.vue'
import ModifiedIcon from './ModifiedIcon.vue'
const props = withDefaults(
defineProps<{ selected?: boolean; modified?: boolean }>(),
{ selected: false, modified: false },
)
const emit = defineEmits<{ revert: [] }>()
</script>

<template>
Expand All @@ -10,6 +15,12 @@ const props = withDefaults(defineProps<{ selected?: boolean }>(), {
<slot />
</button>
<div style="display: flex; align-items: center">
<ModifiedIcon v-if="props.selected && props.modified" />
<ItemButton
v-if="props.selected && props.modified"
@click="() => emit('revert')"
><i-fluent-arrow-undo-20-regular style="font-size: 0.9em"
/></ItemButton>
<slot name="extra"></slot>
</div>
</div>
Expand Down
30 changes: 21 additions & 9 deletions frontend/src/seqvars/components/PredefinedQueryList.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
<script setup lang="ts">
import { SeqvarsPredefinedQuery } from '@varfish-org/varfish-api/lib'
import {
SeqvarsPredefinedQuery,
SeqvarsQueryPresetsSetVersionDetails,
} from '@varfish-org/varfish-api/lib'
import CollapsibleGroup from '@/seqvars/components/CollapsibleGroup.vue'
import Item from '@/seqvars/components/Item.vue'
import ItemButton from '@/seqvars/components/ItemButton.vue'
import { Query } from '@/seqvars/types'
import { matchesPredefinedQuery } from './utils'
const { presets } = defineProps<{ presets: SeqvarsPredefinedQuery[] }>()
const selectedId = defineModel<string | undefined>({ required: true })
const { presets, query } = defineProps<{
presets: SeqvarsQueryPresetsSetVersionDetails
query: Query | null
}>()
const selectedId = defineModel<string | undefined>('selectedId', {
required: true,
})
defineEmits<{ addQuery: [preset: SeqvarsPredefinedQuery] }>()
</script>
Expand All @@ -15,14 +25,16 @@ defineEmits<{ addQuery: [preset: SeqvarsPredefinedQuery] }>()
<CollapsibleGroup title="Presets">
<div style="width: 100%; display: flex; flex-direction: column">
<Item
v-for="preset in presets"
:key="preset.sodar_uuid"
:selected="preset.sodar_uuid === selectedId"
@click="selectedId = preset.sodar_uuid"
v-for="pq in presets.seqvarspredefinedquery_set"
:key="pq.sodar_uuid"
:selected="pq.sodar_uuid === selectedId"
:modified="!!query && !matchesPredefinedQuery(presets, query, pq)"
@click="selectedId = pq.sodar_uuid"
@revert="selectedId = pq.sodar_uuid"
>
<template #default>{{ preset.label }}</template>
<template #default>{{ pq.label }}</template>
<template #extra
><ItemButton @click="$emit('addQuery', preset)"
><ItemButton @click="$emit('addQuery', pq)"
><i-bi-filter style="font-size: 0.9em" /></ItemButton
></template>
</Item>
Expand Down
Loading

0 comments on commit c885421

Please sign in to comment.