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

Add separate about page, editable in admin interface #65

Merged
merged 1 commit into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/src/predicTCR_server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ def runner_result():
sources="TIL;PMBC;Other",
csv_required_columns="barcode;cdr3;chain",
runner_job_timeout_mins=60,
about_md="",
)
)
db.session.commit()
Expand Down
1 change: 1 addition & 0 deletions backend/src/predicTCR_server/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class Settings(db.Model):
sources: Mapped[str] = mapped_column(String, nullable=False)
csv_required_columns: Mapped[str] = mapped_column(String, nullable=False)
runner_job_timeout_mins: Mapped[int] = mapped_column(Integer, nullable=False)
about_md: Mapped[str] = mapped_column(String, nullable=False)

def as_dict(self):
return {c: getattr(self, c) for c in inspect(self).attrs.keys()}
Expand Down
2 changes: 2 additions & 0 deletions backend/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ def test_get_settings_valid(client):
"sources": "TIL;PMBC;Other",
"tumor_types": "Lung;Breast;Other",
"runner_job_timeout_mins": 60,
"about_md": "",
}


Expand All @@ -156,6 +157,7 @@ def test_update_settings_valid(client):
"sources": "a;b;g",
"tumor_types": "1;2;6",
"runner_job_timeout_mins": 12,
"about_md": "# About",
"invalid-key": "invalid",
}
response = client.post("/api/admin/settings", headers=headers, json=new_settings)
Expand Down
3 changes: 3 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"bootstrap-icons": "^1.11.3",
"flowbite": "^2.5.2",
"flowbite-vue": "^0.1.6",
"github-markdown-css": "^5.8.1",
"pinia": "^2.2.2",
"showdown": "^2.1.0",
"vue": "^3.5.10",
"vue-router": "^4.4.5",
"vueperslides": "^3.5.1"
Expand All @@ -27,6 +29,7 @@
"@testing-library/vue": "^8.1.0",
"@types/jsdom": "^21.1.7",
"@types/node": "^22.7.4",
"@types/showdown": "^2.0.6",
"@typescript-eslint/eslint-plugin": "^8.7.0",
"@typescript-eslint/parser": "^8.7.0",
"@vitejs/plugin-vue": "^5.1.4",
Expand Down
46 changes: 46 additions & 0 deletions frontend/pnpm-lock.yaml

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

10 changes: 8 additions & 2 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import {
FwbNavbarLogo,
} from "flowbite-vue";
import { useUserStore } from "@/stores/user";
import { useSettingsStore } from "@/stores/settings";
import FooterComponent from "@/components/FooterComponent.vue";
const userStore = useUserStore();
const settingsStore = useSettingsStore();
settingsStore.refresh();
const login_title = computed(() => {
if (userStore.user !== null) {
return userStore.user.email;
Expand All @@ -21,14 +24,17 @@ const login_title = computed(() => {
<template>
<fwb-navbar>
<template #logo>
<fwb-navbar-logo alt="predicTCR v2" image-url="/logo.png" link="#">
<fwb-navbar-logo alt="predicTCR v2" image-url="/logo.png" link="/">
predicTCR v2
</fwb-navbar-logo>
</template>
<template #default="{ isShowMenu }">
<fwb-navbar-collapse :is-show-menu="isShowMenu">
<fwb-navbar-link link="#">
<RouterLink to="/">About</RouterLink>
<RouterLink to="/">Home</RouterLink>
</fwb-navbar-link>
<fwb-navbar-link link="#">
<RouterLink to="/about">About</RouterLink>
</fwb-navbar-link>
<fwb-navbar-link link="#">
<RouterLink to="/samples">My samples</RouterLink>
Expand Down
41 changes: 41 additions & 0 deletions frontend/src/assets/main.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@
@import "../../node_modules/flowbite-vue/dist/index.css";
@import "github-markdown-css";

@tailwind base;
@tailwind components;
@tailwind utilities;

.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
}

@media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}

/* additional css for markdown rendering to restore ul/ol removed by tailwind */

.markdown-body ul {
list-style-type: disc;
list-style-position: inside;
}

.markdown-body ol {
list-style-type: decimal;
list-style-position: inside;
}

.markdown-body ul ul,
ol ul {
list-style-type: circle;
list-style-position: inside;
margin-left: 15px;
}

.markdown-body ol ol,
ul ol {
list-style-type: lower-latin;
list-style-position: inside;
margin-left: 15px;
}
15 changes: 15 additions & 0 deletions frontend/src/components/HeadingComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script setup lang="ts">
import { FwbJumbotron } from "flowbite-vue";
</script>

<template>
<fwb-jumbotron
header-text="predicTCR v2"
header-classes="text-slate-100"
sub-text="Prediction of tumor-reactive T cells and TCRs from scRNA-seq data."
sub-text-classes="text-slate-300"
class="mb-4 bg-slate-800 bg-splash bg-no-repeat bg-center bg-cover md:rounded-lg py-0 lg:py-0 pt-8 lg:pt-8"
>
<slot></slot>
</fwb-jumbotron>
</template>
19 changes: 19 additions & 0 deletions frontend/src/components/MarkdownComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script setup lang="ts">
import showdown from "showdown";

const props = defineProps({
markdown: {
type: String,
required: true,
},
});

const markdownConverter = new showdown.Converter();
const convertedHtml = markdownConverter.makeHtml(props.markdown);
</script>

<template>
<article class="markdown-body">
<div v-html="convertedHtml"></div>
</article>
</template>
59 changes: 24 additions & 35 deletions frontend/src/components/SettingsTable.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,15 @@
<script setup lang="ts">
import { FwbButton, FwbInput, FwbRange } from "flowbite-vue";
import { ref } from "vue";
import { FwbButton, FwbInput, FwbRange, FwbTextarea } from "flowbite-vue";
import { useSettingsStore } from "@/stores/settings";
import { apiClient, logout } from "@/utils/api-client";
import type { Settings } from "@/utils/types";

const settings = ref(null as Settings | null);

function get_settings() {
apiClient
.get("/settings")
.then((response) => {
settings.value = response.data;
})
.catch((error) => {
if (error.response.status > 400) {
logout();
}
console.log(error);
});
}

get_settings();
const settingsStore = useSettingsStore();
settingsStore.refresh();

function update_settings() {
apiClient
.post("admin/settings", settings.value)
.post("admin/settings", settingsStore.settings)
.then(() => {
get_settings();
console.log("Settings updated");
})
.catch((error) => {
if (error.response.status > 400) {
Expand All @@ -38,54 +21,60 @@ function update_settings() {
</script>

<template>
<div class="flex flex-col m-2 p-2" v-if="settings">
<div class="flex flex-col m-2 p-2" v-if="settingsStore.settings">
<fwb-range
v-model="settings.default_personal_submission_quota"
v-model="settingsStore.settings.default_personal_submission_quota"
:steps="1"
:min="0"
:max="99"
:label="`Default personal quota: ${settings.default_personal_submission_quota}`"
:label="`Default personal quota: ${settingsStore.settings.default_personal_submission_quota}`"
class="mb-2"
/>
<fwb-range
v-model="settings.default_personal_submission_interval_mins"
v-model="settingsStore.settings.default_personal_submission_interval_mins"
:steps="1"
:min="0"
:max="60"
:label="`Default interval between submissions: ${settings.default_personal_submission_interval_mins} minutes`"
:label="`Default interval between submissions: ${settingsStore.settings.default_personal_submission_interval_mins} minutes`"
class="mb-2"
/>
<fwb-range
v-model="settings.global_quota"
v-model="settingsStore.settings.global_quota"
:steps="1"
:min="0"
:max="9999"
:label="`Remaining global quota: ${settings.global_quota}`"
:label="`Remaining global quota: ${settingsStore.settings.global_quota}`"
class="mb-2"
/>
<fwb-input
v-model="settings.tumor_types"
v-model="settingsStore.settings.tumor_types"
class="mb-2"
label="Tumor types (separated by ;)"
></fwb-input>
<fwb-input
v-model="settings.sources"
v-model="settingsStore.settings.sources"
class="mb-2"
label="Sources (separated by ;)"
></fwb-input>
<fwb-input
v-model="settings.csv_required_columns"
v-model="settingsStore.settings.csv_required_columns"
class="mb-2"
label="Required columns in CSV file (separated by ;)"
></fwb-input>
<fwb-range
v-model="settings.runner_job_timeout_mins"
v-model="settingsStore.settings.runner_job_timeout_mins"
:steps="1"
:min="1"
:max="360"
:label="`Timeout for runner jobs: ${settings.runner_job_timeout_mins} minutes`"
:label="`Timeout for runner jobs: ${settingsStore.settings.runner_job_timeout_mins} minutes`"
class="mb-2"
/>
<fwb-textarea
v-model="settingsStore.settings.about_md"
:rows="32"
class="mb-2"
label="About page text (markdown)"
></fwb-textarea>
<fwb-button @click="update_settings" class="mt-2" color="green">
Save settings</fwb-button
>
Expand Down
Loading
Loading