Skip to content

Commit

Permalink
feat: Refurbishing design of Profile page (#214) (#256)
Browse files Browse the repository at this point in the history
  • Loading branch information
gromdimon authored Dec 8, 2023
1 parent 120128f commit 61a59d3
Show file tree
Hide file tree
Showing 19 changed files with 1,150 additions and 393 deletions.
23 changes: 23 additions & 0 deletions frontend/src/api/__tests__/acmgseqvar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@ describe.concurrent('AcmgSeqVar Client', () => {
fetchMocker.resetMocks()
})

it('lists ACMG ratings correctly', async () => {
fetchMocker.mockResponse(JSON.stringify([mockAcmgRating]))

const client = new AcmgSeqVarClient()
const result = await client.listAcmgRatings()

expect(result).toEqual([mockAcmgRating])
})

it('fails to list ACMG ratings', async () => {
fetchMocker.mockResponse((req) => {
if (req.url.includes('acmgseqvar/list')) {
return Promise.resolve(JSON.stringify({ status: 500 }))
}
return Promise.resolve(JSON.stringify({ status: 400 }))
})

const client = new AcmgSeqVarClient()
const result = await client.listAcmgRatings()

expect(result).toEqual({ status: 500 })
})

it('fetches ACMG rating correctly', async () => {
fetchMocker.mockResponse(JSON.stringify(mockAcmgRating))

Expand Down
15 changes: 15 additions & 0 deletions frontend/src/api/acmgseqvar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ export class AcmgSeqVarClient {
this.currentUserId = null
}

/**
* List all ACMG ratings for a user.
*
* @returns The list of ACMG ratings for the user.
*/
async listAcmgRatings(): Promise<any> {
const url = `${this.apiBaseUrl}acmgseqvar/list`
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
credentials: 'include'
})
return await response.json()
}

/**
* Obtains the ACMG rating for a variant.
*
Expand Down
24 changes: 10 additions & 14 deletions frontend/src/components/HeaderDefault.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import { useTheme } from 'vuetify'
const CaseInformationCard = defineAsyncComponent(
() => import('@/components/CaseInformationCard.vue')
)
const UserProfileButton = defineAsyncComponent(() => import('@/components/UserProfileButton.vue'))
const theme = useTheme()
function toggleTheme() {
theme.global.name.value = theme.global.current.value.dark ? 'light' : 'dark'
}
</script>

<template>
Expand All @@ -13,6 +20,7 @@ const UserProfileButton = defineAsyncComponent(() => import('@/components/UserPr
<router-link to="/">
<img
id="logo"
class="ml-4 mr-3"
style="vertical-align: middle"
src="@/assets/reev-logo.svg"
alt="logo"
Expand All @@ -22,7 +30,8 @@ const UserProfileButton = defineAsyncComponent(() => import('@/components/UserPr
<router-link to="/"> REEV Explains and Evaluates Variants </router-link>
</v-toolbar-title>
<v-spacer />
<v-toolbar-items class="topbar-links">
<v-btn @click="toggleTheme">toggle theme</v-btn>
<v-toolbar-items>
<v-dialog scrollable width="auto" location="top">
<template #activator="{ props }">
<v-btn class="mr-4" prepend-icon="mdi-information-outline" v-bind="props">
Expand Down Expand Up @@ -61,19 +70,6 @@ const UserProfileButton = defineAsyncComponent(() => import('@/components/UserPr

<style scoped>
.top-bar {
background-color: white;
border-bottom: 2px solid #455a64;
}
.topbar-links {
display: flex;
margin: 0 10px;
}
#logo {
margin-left: 25px;
margin-right: 10px;
margin-top: 10px;
margin-bottom: 10px;
}
</style>
25 changes: 11 additions & 14 deletions frontend/src/components/HeaderDetailPage.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { defineAsyncComponent, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useTheme } from 'vuetify'
import { search } from '@/lib/utils'
Expand All @@ -25,10 +26,15 @@ const props = withDefaults(defineProps<Props>(), {
})
const router = useRouter()
const theme = useTheme()
const searchTermRef = ref(props.searchTerm)
const genomeReleaseRef = ref(props.genomeRelease)
function toggleTheme() {
theme.global.name.value = theme.global.current.value.dark ? 'light' : 'dark'
}
/**
* Perform a search based on the current search term and genome release.
*
Expand Down Expand Up @@ -57,6 +63,7 @@ watch(() => props.searchTerm, updateTerms)
<router-link to="/">
<img
id="logo"
class="ml-4 mr-3"
style="vertical-align: middle"
src="@/assets/reev-logo.svg"
alt="logo"
Expand All @@ -71,8 +78,10 @@ watch(() => props.searchTerm, updateTerms)
density="compact"
@click-search="performSearch"
/>
<v-spacer></v-spacer>
<v-toolbar-items class="topbar-links">

<v-spacer />
<v-btn @click="toggleTheme">toggle theme</v-btn>
<v-toolbar-items>
<v-dialog scrollable width="auto" location="top">
<template #activator="{ props: vProps }">
<v-btn class="mr-4" prepend-icon="mdi-information-outline" v-bind="vProps">
Expand Down Expand Up @@ -111,23 +120,11 @@ watch(() => props.searchTerm, updateTerms)

<style scoped>
.top-bar {
background-color: white;
border-bottom: 2px solid #455a64;
}
.top-search-bar {
display: flex;
width: 50%;
}
.topbar-links {
display: flex;
margin: 0 10px;
}
#logo {
margin-left: 25px;
margin-top: 10px;
margin-bottom: 10px;
}
</style>
61 changes: 61 additions & 0 deletions frontend/src/components/Profile/BookmarksCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<script setup lang="ts">
import { onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { search } from '@/lib/utils'
import { useBookmarksStore } from '@/stores/bookmarks'
const bookmarksStore = useBookmarksStore()
const router = useRouter()
/**
* Perform a search based on the bookmark id.
*
* If a route is found for the search term then redirect to that route.
* Otherwise log an error.
*
* @param query Query to search for
*/
const performSearch = async (query: string) => {
const routeLocation: any = await search(query, 'grch37')
if (routeLocation) {
router.push(routeLocation)
} else {
console.error(`no route found for ${query}`)
}
}
onMounted(async () => {
await bookmarksStore.loadBookmarks()
})
</script>

<template>
<v-card class="mx-auto pa-4 pb-8 mt-3" rounded="lg">
<v-card-title>Your bookmarks:</v-card-title>
<v-card-text>
<v-list v-if="bookmarksStore.bookmarks.length">
<v-list-item
v-for="bookmark in bookmarksStore.bookmarks"
:key="bookmark.id"
density="compact"
>
<v-list-item-title>
<v-btn color="primary" @click="performSearch(bookmark.obj_id)">
{{ bookmark.obj_id }}
</v-btn>
<v-btn
class="ma-2"
color="secondary"
icon
@click="bookmarksStore.deleteBookmark(bookmark.obj_type, bookmark.obj_id)"
>
<v-icon>mdi-delete</v-icon>
</v-btn>
</v-list-item-title>
</v-list-item>
</v-list>
<v-card-subtitle v-else> You have no bookmarks yet. </v-card-subtitle>
</v-card-text>
</v-card>
</template>
Loading

0 comments on commit 61a59d3

Please sign in to comment.