Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/assembly #15

Closed
wants to merge 11 commits into from
44 changes: 40 additions & 4 deletions src/BakrepApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BaktaResultSchema, type BaktaResult } from "./model/BaktaResults";
import { CheckmResultSchema, type CheckmResult } from "./model/CheckmResults";
import { DatasetSchema, type Dataset } from "./model/Dataset";
import { GtdbtkResultSchema, type GtdbtkResult } from "./model/GtdbtkResult";
import { MlstResultSchema, type MlstResult } from "./model/MlstResults";

let baseurl: string = "http://localhost:8080";
function initApi(url: string) {
Expand All @@ -12,6 +14,8 @@ interface BakrepApi {
fetchUrlContentAsJson(url: string): Promise<any>;
fetchBaktaResult(dataset: Dataset): Promise<BaktaResult>;
fetchGtdbtkResult(dataset: Dataset): Promise<GtdbtkResult>;
fetchCheckmResult(dataset: Dataset): Promise<CheckmResult>;
fetchMlstResult(dataset: Dataset): Promise<MlstResult>;
}

class BakrepApiImpl implements BakrepApi {
Expand Down Expand Up @@ -49,19 +53,51 @@ class BakrepApiImpl implements BakrepApi {
return fetch(bakta[0].url).then(this.toJson).then(BaktaResultSchema.parse);
}
fetchGtdbtkResult(dataset: Dataset): Promise<GtdbtkResult> {
const bakta = dataset.results.filter(
const gtdb = dataset.results.filter(
(x) => x.attributes.tool === "gtdbtk" && x.attributes.filetype === "json"
);
if (bakta.length == 0) {
if (gtdb.length == 0) {
return Promise.reject(
`Unsupported: Dataset does not contain gtdbtk result: ${dataset}`
);
}
if (bakta.length > 1)
if (gtdb.length > 1)
return Promise.reject(
`Unsupported: Dataset constains multiple gtdbtk results: ${dataset}`
);
return fetch(bakta[0].url).then(this.toJson).then(GtdbtkResultSchema.parse);
return fetch(gtdb[0].url).then(this.toJson).then(GtdbtkResultSchema.parse);
}
fetchCheckmResult(dataset: Dataset): Promise<CheckmResult> {
const checkm = dataset.results.filter(
(x) => x.attributes.tool === "checkm2" && x.attributes.filetype === "json"
);
if (checkm.length == 0) {
return Promise.reject(
`Unsupported: Dataset does not contain checkm result: ${dataset}`
);
}
if (checkm.length > 1) {
return Promise.reject(
`Unsupported: Dataset constains multiple checkm results: ${dataset}`
);
}
return fetch(checkm[0].url).then(this.toJson).then(CheckmResultSchema.parse);
}
fetchMlstResult(dataset: Dataset): Promise<MlstResult> {
const mlst = dataset.results.filter(
(x) => x.attributes.tool === "mlst" && x.attributes.filetype === "json"
);
if (mlst.length == 0) {
return Promise.reject(
`Unsupported: Dataset does not contain mlst result: ${dataset}`
);
}
if (mlst.length > 1) {
return Promise.reject(
`Unsupported: Dataset constains multiple mlst results: ${dataset}`
);
}
return fetch(mlst[0].url).then(this.toJson).then(MlstResultSchema.parse);
}
}

Expand Down
67 changes: 27 additions & 40 deletions src/components/Footer.vue
Original file line number Diff line number Diff line change
@@ -1,41 +1,28 @@
<script setup lang="ts">
</script>

<template>
<div class="container">
<footer class="py-3 my-3">
<div class="d-flex flex-row">
<a href="https://www.uni-giessen.de/de/fbz/fb08/Inst/bioinformatik/" target="_blank">
<img
src="@/assets/images/CB.AG_Logo.svg"
height="200"
width="350"
/>
</a>
<a href="">
<img
src="@/assets/images/De.NBI_Logo.svg"
width="350"
height="160"
/>
</a>
<div class="mx-5 vr"></div>
<ul class="nav pb-3 mb-3 justify-content-center border-bottom d-flex flex-column">
<li class="navitem">
<router-link class="nav-link px-2 text-muted" to="/">Home</router-link>
</li>
<li class="navitem">
<router-link class="nav-link px-2 text-muted" to="/about">About</router-link>
</li>
<li class="navitem">
<router-link class="nav-link px-2 text-muted" to="/imprint">Imprint</router-link>
</li>
</ul>
</div>

<p class="text-center text-muted">
2023 - Bakta
</p>
</footer>
</div>
</template>
<div class="container">
<footer class="py-3 my-3">
<div class="d-flex flex-column flex-xl-row justify-content-center">
<a href="https://www.uni-giessen.de/de/fbz/fb08/Inst/bioinformatik/" target="_blank">
<img src="@/assets/images/CB.AG_Logo.svg" height="200" width="350" />
</a>
<a href="">
<img src="@/assets/images/De.NBI_Logo.svg" width="350" height="160" />
</a>
<div class="mx-5 vr justify-self-center"></div>
<ul class="nav pb-3 mb-3 justify-content-center flex-xl-column flex-row">
<li class="navitem">
<router-link class="nav-link px-2 text-muted" to="/">Home</router-link>
</li>
<li class="navitem">
<router-link class="nav-link px-2 text-muted" to="/about">About</router-link>
</li>
<li class="navitem">
<router-link class="nav-link px-2 text-muted" to="/imprint">Imprint</router-link>
</li>
</ul>
</div>

<p class="text-center text-muted">2023 - Bakta</p>
</footer>
</div>
</template>
58 changes: 28 additions & 30 deletions src/components/Navbar.vue
Original file line number Diff line number Diff line change
@@ -1,39 +1,37 @@
<script setup lang="ts">
import { ref } from 'vue';
const items = ref([
{href: {'name': 'home' }, text: 'Home'},
{href: {'name': 'browse' }, text: 'Browse'},
{href: {'name': 'search'}, text: 'Search'}
//{href: {'name': 'about' }, text: 'About'},
{ href: { 'name': 'home' }, text: 'Home' },
{ href: { 'name': 'browse' }, text: 'Browse' },
{ href: { 'name': 'search' }, text: 'Search' },
{ href: { 'name': 'about' }, text: 'About' },
])
</script>

<template>
<nav class="navbar navbar-expand-lg navbar-light fixed-top bg-light navbar-scroll">
<div class="container-fluid">
<router-link class="navbar-brand" to="/">BakRep Web</router-link>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<template v-for="{href, text} in items">
<li>
<router-link class="nav-link" :to="href">{{ text }}</router-link>
</li>
</template>
</ul>
<ul class="navbar-nav">
<!-- <li><a class="nav-link " href="https://www.microbiologyresearch.org/content/journal/mgen/10.1099/mgen.0.000685">Citation</a></li> -->
<li><a style="font-size: 2em" class="nav-link" href="https://github.com/ag-computational-bio" target="_blank"><i class="bi bi-github text-dark"></i></a></li>
</ul>
</div>
</div>
</nav>
<nav class="navbar navbar-expand-lg navbar-light fixed-top bg-light navbar-scroll">
<div class="container-fluid">
<router-link class="navbar-brand" to="/">BakRep Web</router-link>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<template v-for="{ href, text } in items">
<li>
<router-link class="nav-link" :to="href">{{ text }}</router-link>
</li>
</template>
</ul>
<ul class="navbar-nav">
<!-- <li><a class="nav-link " href="https://www.microbiologyresearch.org/content/journal/mgen/10.1099/mgen.0.000685">Citation</a></li> -->
<li><a style="font-size: 2em" class="nav-link" href="https://github.com/ag-computational-bio" target="_blank"><i
class="bi bi-github text-dark"></i></a></li>
</ul>
</div>
</div>
</nav>
</template>

<style>

</style>
<style></style>
23 changes: 23 additions & 0 deletions src/model/CheckmResults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { z } from "zod";

const QualitySchema = z.object({
completeness: z.number(),
contamination: z.number(),
});

const CalculationSchema = z.object({
model: z.string(),
translation_table: z.number(),
notes: z.string(),
})

const CheckmResultSchema = z.object({
quality: QualitySchema,
calculation: CalculationSchema,
});

export type Quality = z.infer<typeof QualitySchema>;
export type Calculation = z.infer<typeof CalculationSchema>;
export type CheckmResult = z.infer<typeof CheckmResultSchema>;

export { CheckmResultSchema };
18 changes: 18 additions & 0 deletions src/model/MlstResults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { z } from "zod";

const MlstEntrySchema = z.object({
allels: z.optional(z.nullable(z.object({
// z.set(z.string()),
}))),
id: z.string(),
sequence_type: z.string(),
scheme: z.string(),
filename: z.string(),
});

const MlstResultSchema = z.array(MlstEntrySchema);

export type MlstEntry = z.infer<typeof MlstEntrySchema>;
export type MlstResult = z.infer<typeof MlstResultSchema>;

export { MlstResultSchema, MlstEntrySchema };
20 changes: 8 additions & 12 deletions src/views/AboutView.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
<template>
<div class="about">
<h1>This is an about page</h1>
<div class="container">
<h1>About Bakrep</h1>

Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolor, porro. Debitis numquam unde fugit ut, molestias cumque quibusdam error fugiat vitae. Enim quam pariatur deserunt molestias maxime autem voluptatum omnis?
Eius tenetur culpa tempore accusantium perspiciatis ullam voluptatibus vel facilis debitis alias quos dignissimos dolore, odio illum facere repellat nostrum id! Eius est maxime, eveniet aliquid alias accusantium ab dolorum?
Quisquam cupiditate, dolor quae fuga architecto similique expedita blanditiis tempore et. Dolorum minus ex recusandae dolor fugiat laborum praesentium eum, magnam earum ipsum harum beatae distinctio, voluptatem assumenda iusto sunt.
Distinctio ad iure eum officia sit sed, asperiores praesentium reprehenderit laudantium maiores tenetur recusandae, nemo sint! Voluptates ea enim accusamus vitae excepturi praesentium. Cupiditate facilis ducimus quo dolores laboriosam eum?
Non temporibus ex enim maxime molestias, quidem rem cupiditate nemo! A aspernatur ut, aut praesentium repellat cum id. Vero soluta velit sapiente aliquam quas repudiandae iure atque fugiat vel ad?
</div>
</template>

<style>
@media (min-width: 1024px) {
.about {
min-height: 100vh;
display: flex;
align-items: center;
}
}
</style>
71 changes: 51 additions & 20 deletions src/views/show-results/DatasetSummary.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,61 @@
<template>
<div v-if="annotation">
<display-tuple label="Genus:" :value="annotation.genome.genus" />
<display-tuple label="Species:" :value="annotation.genome.species" />
<display-tuple label="Strain:" :value="annotation.genome.strain" />
<display-tuple label="Completeness:" :value="annotation.genome.complete" />
<display-tuple label="Gram:" :value="annotation.genome.gram" />
<display-tuple
label="Translation Table:"
:value="annotation.genome.translation_table"
/>
<display-tuple label="Genome Size:" :value="annotation.stats.size" />
<display-tuple label="GC Ratio:" :value="annotation.stats.gc" />
<display-tuple label="N Ratio" :value="annotation.stats.n_ratio" />
<display-tuple label="N50" :value="annotation.stats.n50" />
<display-tuple
label="Coding Ratio"
:value="annotation.stats.coding_ratio"
/>
</div>
<table v-if="annotation" class="table">
<tr>
<th scope="row">Genus</th>
<td>{{ annotation.genome.genus }}</td>
</tr>
<tr>
<th scope="row">Species</th>
<td>{{ annotation.genome.species }}</td>
</tr>
<tr>
<th scope="row">Strain</th>
<td>{{ annotation.genome.strain }}</td>
</tr>
<tr>
<th scope="row">Complete</th>
<td>{{ annotation.genome.complete }}</td>
</tr>
<tr>
<th scope="row">Size</th>
<td>{{ annotation.stats.size }}</td>
</tr>
<tr>
<th scope="row">GC Ratio</th>
<td>{{ ratioToPercentage(annotation.stats.gc) }}</td>
</tr>
<tr>
<th scope="row">n Ratio</th>
<td>
<NRatio :value="annotation.stats.n_ratio"></NRatio>
</td>
</tr>
<tr>
<th scope="row">Coding Ratio</th>
<td>
{{ ratioToPercentage(annotation.stats.coding_ratio) }}
</td>
</tr>
</table>
<div v-else>No bakta result provided</div>
</template>
<script setup lang="ts">
import NRatio from "@/components/NRatio.vue";
import type { BaktaResult } from "@/model/BaktaResults";
import { ratioToPercentage } from "@/util";
import type { PropType } from "vue";
import DisplayTuple from "@/views/show-results/bakta/DisplayTuple.vue";
defineProps({
annotation: { type: Object as PropType<BaktaResult>, default: undefined },
});
</script>

<style>
th {
font-weight: bold;
}

td {
font-weight: bold;
color: gray;
}
</style>
Loading