Skip to content

Commit

Permalink
fix: resolving issues with caseInfo storage and API (#454) (#456)
Browse files Browse the repository at this point in the history
  • Loading branch information
holtgrewe authored Feb 7, 2024
1 parent 62bfd70 commit 2f3ea9d
Show file tree
Hide file tree
Showing 17 changed files with 151 additions and 70 deletions.
2 changes: 1 addition & 1 deletion backend/alembic/versions/4f3b20f156c1_init_caseinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def upgrade():
sa.Column("sex", sa.Enum("Male", "Female", "Unknown", name="sex"), nullable=True),
sa.Column("age_of_onset_month", sa.Integer(), nullable=True),
sa.Column(
"ethinicity",
"ethnicity",
sa.Enum(
"AfricanAmerican",
"AshkenaziJewish",
Expand Down
4 changes: 2 additions & 2 deletions backend/app/models/caseinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class CaseInfo(Base):
affected_family_members: bool
sex: Sex
age_of_onset_month: int
ethinicity: Ethnicity
ethnicity: Ethnicity
zygosity: Zygosity
family_segregation: bool
else:
Expand All @@ -65,7 +65,7 @@ class CaseInfo(Base):
#: Age of onset of the patient.
age_of_onset_month = Column(Integer, nullable=True)
#: Ethnicity of the patient.
ethinicity = Column(Enum(Ethnicity), nullable=True)
ethnicity = Column(Enum(Ethnicity), nullable=True)
#: Zygosity of the patient.
zygosity = Column(Enum(Zygosity), nullable=True)
#: Family segregation of the patient.
Expand Down
2 changes: 1 addition & 1 deletion backend/app/schemas/caseinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class CaseInfoBase(BaseModel):
affected_family_members: bool | None = None
sex: Sex = Sex.Unknown
age_of_onset_month: int | None = None
ethinicity: Ethnicity = Ethnicity.Unknown
ethnicity: Ethnicity = Ethnicity.Unknown
zygosity: Zygosity = Zygosity.Unknown
family_segregation: bool | None = None

Expand Down
4 changes: 2 additions & 2 deletions backend/tests/api/api_v1/test_caseinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ async def test_create_caseinfo(
"affected_family_members": True,
"sex": "reev:unknown_sex",
"age_of_onset_month": 20,
"ethinicity": "reev:unknown_ethnicity",
"ethnicity": "reev:unknown_ethnicity",
"zygosity": "reev:unknown_zygosity",
"family_segregation": True,
},
Expand All @@ -53,7 +53,7 @@ async def test_create_caseinfo(
assert response.json()["affected_family_members"] == True
assert response.json()["sex"] == "reev:unknown_sex"
assert response.json()["age_of_onset_month"] == 20
assert response.json()["ethinicity"] == "reev:unknown_ethnicity"
assert response.json()["ethnicity"] == "reev:unknown_ethnicity"
assert response.json()["zygosity"] == "reev:unknown_zygosity"
assert response.json()["family_segregation"] == True

Expand Down
8 changes: 4 additions & 4 deletions backend/tests/crud/test_caseinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def case_create() -> CaseInfoCreate:
affected_family_members=True,
sex=Sex.Unknown,
age_of_onset_month=20,
ethinicity=Ethnicity.Unknown,
ethnicity=Ethnicity.Unknown,
zygosity=Zygosity.Unknown,
family_segregation=True,
user=uuid.uuid4(),
Expand All @@ -48,7 +48,7 @@ async def test_create_get_caseinfo(db_session: AsyncSession, case_create: CaseIn
assert caseinfo_postcreate.affected_family_members == stored_item.affected_family_members
assert caseinfo_postcreate.sex == stored_item.sex
assert caseinfo_postcreate.age_of_onset_month == stored_item.age_of_onset_month
assert caseinfo_postcreate.ethinicity == stored_item.ethinicity
assert caseinfo_postcreate.ethnicity == stored_item.ethnicity
assert caseinfo_postcreate.zygosity == stored_item.zygosity
assert caseinfo_postcreate.family_segregation == stored_item.family_segregation

Expand Down Expand Up @@ -81,7 +81,7 @@ async def test_get_multi_by_user(db_session: AsyncSession, case_create: CaseInfo
assert caseinfo_postcreate.affected_family_members == stored_items[0].affected_family_members
assert caseinfo_postcreate.sex == stored_items[0].sex
assert caseinfo_postcreate.age_of_onset_month == stored_items[0].age_of_onset_month
assert caseinfo_postcreate.ethinicity == stored_items[0].ethinicity
assert caseinfo_postcreate.ethnicity == stored_items[0].ethnicity
assert caseinfo_postcreate.zygosity == stored_items[0].zygosity
assert caseinfo_postcreate.family_segregation == stored_items[0].family_segregation

Expand All @@ -105,6 +105,6 @@ async def test_get_by_user(db_session: AsyncSession, case_create: CaseInfoCreate
assert caseinfo_postcreate.affected_family_members == stored_item.affected_family_members
assert caseinfo_postcreate.sex == stored_item.sex
assert caseinfo_postcreate.age_of_onset_month == stored_item.age_of_onset_month
assert caseinfo_postcreate.ethinicity == stored_item.ethinicity
assert caseinfo_postcreate.ethnicity == stored_item.ethnicity
assert caseinfo_postcreate.zygosity == stored_item.zygosity
assert caseinfo_postcreate.family_segregation == stored_item.family_segregation
17 changes: 17 additions & 0 deletions docs/dev_quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,23 @@ You have to restart jupyterlab manually.
Now you can navigate to the frontend development server at http://localhost:8081.
This server will transparently forward the API requests to the backend server at http://localhost:8081.

---------------
Troubleshooting
---------------

Issues with nested git submodules.
We have put the shared code into ``frontend/src/ext/reev-frontend-lib``.
Make sure that you get a fresh clone of the repository with the ``--recursive`` flag.
To initialize the submodules, use ``git submodule update --init --recursive``.
You can reset the submodule to the version stored in the main ``reev`` repository with ``git submodule foreach --recursive git reset --hard``.

Issues with ``reev-frontend-lib`` as a submodule.
Having the library as a submodule is useful for development.
There are some drawbacks.
If you see **weird issues with typescript that you don't understand**, try to ``rm -rf frontend/src/ext/reev-frontend-lib/{node_modules,dist}``.
Such issues include problems with assigning the reactive classes from ``vue``, such as ``ref`` and ``computed``, or other weird stuff with types.
In this case, try to clear out the directories described above and restart VS Code.

-----
Notes
-----
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/api/caseInfo/api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ const mockCaseInfo: CaseInfo = {
diseases: [],
hpoTerms: [],
inheritance: Inheritance.Unknown,
affectedFamilyMembers: null,
affectedFamilyMembers: undefined,
sex: Sex.Unknown,
ageOfOnsetMonths: null,
ageOfOnsetMonths: undefined,
ethnicity: Ethnicity.Unknown,
zygosity: Zygosity.Unknown,
familySegregation: null
familySegregation: undefined
}

describe.concurrent('CaseInfo Client', () => {
Expand Down
67 changes: 45 additions & 22 deletions frontend/src/api/caseInfo/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,42 +51,46 @@ export enum Zygosity {

/** Case Info as returned by API */
export interface CaseInfo$Api {
id?: string
user?: string
affected_family_members: boolean | null
age_of_onset_month: number | null
diseases: any[] // Replace with the actual type from your API
ethinicity: string
ethnicity: string
family_segregation: boolean | null
hpo_terms: any[] // Replace with the actual type from your API
id: string
inheritance: string | null
pseudonym: string
sex: string | null
user: string
zygosity: string
}

/** Interface for the case data, for storage and API. */
export interface CaseInfo {
/* The case pseudonym. */
/** The case info ID. */
id?: string
/** The user ID. */
user?: string
/** The case pseudonym. */
pseudonym: string
/* Orphanet / OMIM disease(s). */
/** Orphanet / OMIM disease(s). */
diseases: OmimTerm[]
/* HPO terms. */
/** HPO terms. */
hpoTerms: HpoTerm[]
/* Inheritance. */
/** Inheritance. */
inheritance: Inheritance
/* Affected family members. */
affectedFamilyMembers: boolean | null
/* Sex. */
/** Affected family members. */
affectedFamilyMembers?: boolean
/** Sex. */
sex: Sex
/* Age of onset in month. */
ageOfOnsetMonths: number | null
/* Ethnicity. */
/** Age of onset in month. */
ageOfOnsetMonths?: number
/** Ethnicity. */
ethnicity: Ethnicity
/* Zygosity. */
/** Zygosity. */
zygosity: Zygosity
/* Family segregation. */
familySegregation: boolean | null
/** Family segregation. */
familySegregation?: boolean
}

/**
Expand All @@ -95,16 +99,35 @@ export interface CaseInfo {
export class CaseInfo$Type {
fromJson(apiResponse: CaseInfo$Api): CaseInfo {
return {
id: apiResponse.id,
user: apiResponse.user,
pseudonym: apiResponse.pseudonym,
diseases: apiResponse.diseases,
hpoTerms: apiResponse.hpo_terms,
hpoTerms: apiResponse.hpo_terms ?? [],
inheritance: apiResponse.inheritance as Inheritance,
affectedFamilyMembers: apiResponse.affected_family_members,
sex: apiResponse.sex as Sex,
ageOfOnsetMonths: apiResponse.age_of_onset_month,
ethnicity: apiResponse.ethinicity as Ethnicity,
affectedFamilyMembers: apiResponse.affected_family_members ?? undefined,
sex: (apiResponse.sex as Sex) ?? undefined,
ageOfOnsetMonths: apiResponse.age_of_onset_month ?? undefined,
ethnicity: apiResponse.ethnicity as Ethnicity,
zygosity: apiResponse.zygosity as Zygosity,
familySegregation: apiResponse.family_segregation
familySegregation: apiResponse.family_segregation ?? undefined
}
}

toJson(caseInfo: CaseInfo): CaseInfo$Api {
return {
id: caseInfo.id,
user: caseInfo.user,
pseudonym: caseInfo.pseudonym,
diseases: caseInfo.diseases,
hpo_terms: caseInfo.hpoTerms,
inheritance: caseInfo.inheritance,
affected_family_members: caseInfo.affectedFamilyMembers ?? null,
sex: caseInfo.sex,
age_of_onset_month: caseInfo.ageOfOnsetMonths ?? null,
ethnicity: caseInfo.ethnicity,
zygosity: caseInfo.zygosity,
family_segregation: caseInfo.familySegregation ?? null
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ import {
StorageMode,
Zygosity,
ZygosityLabels,
ethinicityLabels,
ethnicityLabels,
useCaseInfoStore
} from '@/stores/caseInfo'
import { useTermsStore } from '@/stores/terms'
/** This component's emits. */
const emit = defineEmits<{
(eventName: 'clickClose'): void
}>()
const caseStore = useCaseInfoStore()
const termsStore = useTermsStore()
const cadaPrioStore = useCadaPrioStore()
Expand All @@ -41,7 +46,7 @@ const inheritanceOptions = computed(() => {
const ethnicityOptions = computed(() => {
return Object.values(Ethnicity).map((value) => {
return {
text: ethinicityLabels.get(value),
text: ethnicityLabels.get(value),
value: value
}
})
Expand Down Expand Up @@ -278,8 +283,16 @@ watch(
/>

<!-- Buttons -->
<v-btn class="ml-2" @click="saveChanges"> Save Changes </v-btn>
<v-btn class="ml-2" color="secondary" @click="deleteCaseInformation">
<v-btn class="ml-2" color="primary" @click="saveChanges"> Save Changes </v-btn>
<v-btn class="ml-2" color="primary" @click="emit('clickClose')">
Close Window
</v-btn>
<v-btn
class="ml-2"
color="warning"
variant="outlined"
@click="deleteCaseInformation"
>
Delete Case info
</v-btn>
</v-form>
Expand Down
21 changes: 13 additions & 8 deletions frontend/src/components/PageHeader/PageHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ const searchTermRef = ref<string>('')
/** Component state; genome build. */
const genomeBuildRef = ref<GenomeBuild>('grch37')
/** Whether to show the case info box. */
const showCaseInfo = ref<boolean>(false)
/** Helper function to between light and dark theme. */
function toggleTheme() {
theme.global.name.value = theme.global.current.value.dark ? 'customLightTheme' : 'dark'
Expand Down Expand Up @@ -80,16 +83,12 @@ function toggleTheme() {
<v-icon>mdi-theme-light-dark</v-icon>
</v-btn>

<v-dialog scrollable width="auto" location="top">
<template #activator="{ props: vProps }">
<v-btn class="mr-4" prepend-icon="mdi-account-group" v-bind="vProps"> Case Info </v-btn>
</template>
<v-card>
<CaseInformationCard />
</v-card>
</v-dialog>
<v-btn class="mr-4" prepend-icon="mdi-account-group" @click="showCaseInfo = true">
Case Info
</v-btn>

<UserProfileButton />

<v-menu id="menu">
<template #activator="{ props: vProps }">
<v-btn icon="mdi-dots-vertical" v-bind="vProps" />
Expand All @@ -112,4 +111,10 @@ function toggleTheme() {
</v-menu>
</v-container>
</v-app-bar>

<v-dialog v-model="showCaseInfo" scrollable width="auto" location="top">
<v-card>
<CaseInformationCard @click-close="showCaseInfo = false" />
</v-card>
</v-dialog>
</template>
4 changes: 2 additions & 2 deletions frontend/src/components/ProfileCaseCard/ProfileCaseCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
SexLabels,
Zygosity,
ZygosityLabels,
ethinicityLabels,
ethnicityLabels,
useCaseInfoStore
} from '@/stores/caseInfo'
import { useTermsStore } from '@/stores/terms'
Expand Down Expand Up @@ -41,7 +41,7 @@ const inheritanceOptions = computed(() => {
const ethnicityOptions = computed(() => {
return Object.values(Ethnicity).map((value) => {
return {
text: ethinicityLabels.get(value),
text: ethnicityLabels.get(value),
value: value
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ component via the `errorDisplay` event and are handled there.
<script setup lang="ts">
import DocsLink from '@bihealth/reev-frontend-lib/components/DocsLink/DocsLink.vue'
import { type Seqvar } from '@bihealth/reev-frontend-lib/lib/genomicVars'
import { StoreState } from '@bihealth/reev-frontend-lib/stores'
import { computed, onMounted, ref, watch } from 'vue'
import { useTheme } from 'vuetify'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ component via the `errorDisplay` event and are handled there.
<script setup lang="ts">
import DocsLink from '@bihealth/reev-frontend-lib/components/DocsLink/DocsLink.vue'
import type { Strucvar } from '@bihealth/reev-frontend-lib/lib/genomicVars'
import { StoreState } from '@bihealth/reev-frontend-lib/stores'
import { computed, onMounted, ref, watch } from 'vue'
import { useStrucvarAcmgRatingStore } from '@/stores/strucvarAcmgRating'
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/stores/caseInfo/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ export const SexLabels = new Map<Sex, string>([

/** Default case information. */
export const DEFAULT_CASE_INFO: CaseInfo = {
id: 'iduuid',
user: 'useruuid',
pseudonym: '',
diseases: [],
hpoTerms: [],
inheritance: Inheritance.Unknown,
affectedFamilyMembers: null,
affectedFamilyMembers: undefined,
sex: Sex.Unknown,
ageOfOnsetMonths: null,
ageOfOnsetMonths: undefined,
ethnicity: Ethnicity.Unknown,
zygosity: Zygosity.Unknown,
familySegregation: null
familySegregation: undefined
}

/** Labels for `Zygosity`. */
Expand All @@ -33,7 +35,7 @@ export const ZygosityLabels = new Map<Zygosity, string>([
])

/** Labels for `Ethnicity`. */
export const ethinicityLabels = new Map<Ethnicity, string>([
export const ethnicityLabels = new Map<Ethnicity, string>([
[Ethnicity.AfricanAmerican, 'African American'],
[Ethnicity.AshkenaziJewish, 'Ashkenazi Jewish'],
[Ethnicity.EastAsian, 'East Asian'],
Expand Down
Loading

0 comments on commit 2f3ea9d

Please sign in to comment.