feat: metadata
Docker Build / build (push) Has been cancelled
Python Lint CI / ruff (push) Has been cancelled
Python Lint CI / ruff-format-check (push) Has been cancelled
Python Lint CI / ty (push) Has been cancelled
TS Lint / ESLint (push) Has been cancelled
TS Lint / Oxlint (push) Has been cancelled
TS Lint / TypeScript (push) Has been cancelled

This commit is contained in:
2026-07-16 16:36:55 +02:00
parent 603bd9f108
commit 6a0e162596
6 changed files with 44 additions and 3 deletions
+13
View File
@@ -6,6 +6,7 @@ import flask_limiter
import flask_limiter.util import flask_limiter.util
import gunicorn.app.base import gunicorn.app.base
import tortoise import tortoise
from tortoise.functions import Count
from app import PKG_NAME from app import PKG_NAME
from app.lang import get_lang from app.lang import get_lang
@@ -56,6 +57,18 @@ class Server(gunicorn.app.base.BaseApplication):
lang=lambda key: get_lang(locale, key), lang=lambda key: get_lang(locale, key),
) )
@self.app.route("/api/meta", methods=["GET"])
async def metadata() -> dict:
return {
"tasks": await Task.all().count(),
"lists": (
await Task.all()
.annotate(count=Count("list_name", distinct=True))
.first()
.values("count")
)["count"],
}
@self.app.route("/api/lists/<list_name>/tasks", methods=["GET"]) @self.app.route("/api/lists/<list_name>/tasks", methods=["GET"])
async def get_tasks(list_name: str) -> list: async def get_tasks(list_name: str) -> list:
return await Task.filter(list_name=list_name[:128]).values() return await Task.filter(list_name=list_name[:128]).values()
+2 -1
View File
@@ -84,5 +84,6 @@
"save_button": "Save task", "save_button": "Save task",
"clone_button": "Clone task", "clone_button": "Clone task",
"delete_button": "Delete task", "delete_button": "Delete task",
"recent": "Recent lists" "recent": "Recent lists",
"metadata": "{lists} lists / {tasks} tasks"
} }
+2 -1
View File
@@ -84,5 +84,6 @@
"save_button": "Sauvegarder la tâche", "save_button": "Sauvegarder la tâche",
"clone_button": "Cloner la tâche", "clone_button": "Cloner la tâche",
"delete_button": "Supprimer la tâche", "delete_button": "Supprimer la tâche",
"recent": "Listes récentes" "recent": "Listes récentes",
"metadata": "{lists} listes / {tasks} tâches"
} }
+6
View File
@@ -0,0 +1,6 @@
import type { Metadata } from "@/types";
export async function getMetadata(): Promise<Metadata> {
const response = await fetch(`/api/meta`);
return await response.json();
}
+16 -1
View File
@@ -1,9 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { defineAsyncComponent } from "vue"; import { getMetadata } from "@/api/meta";
import type { Metadata } from "@/types";
import { defineAsyncComponent, onBeforeMount, ref } from "vue";
const metadata = ref<Metadata|null>(null);
const LangInput = defineAsyncComponent( const LangInput = defineAsyncComponent(
() => import("@/components/LangInput.vue"), () => import("@/components/LangInput.vue"),
); );
function fetchMetadata() {
void getMetadata()
.then((data) => {
metadata.value = data;
setTimeout(fetchMetadata, 600000);
});
}
onBeforeMount(fetchMetadata);
</script> </script>
<template> <template>
@@ -19,6 +33,7 @@ const LangInput = defineAsyncComponent(
> >
klemek klemek
</a> </a>
<span v-if="metadata">- {{ $t("metadata", metadata) }}</span>
</p> </p>
</aside> </aside>
</footer> </footer>
+5
View File
@@ -46,3 +46,8 @@ export interface Alert {
created: Date; created: Date;
seconds: number; seconds: number;
} }
export interface Metadata {
tasks: number;
lists: number;
}