feat: add list name and task count to list viw
TS Lint / TypeScript (push) Successful in 5m45s
TS Lint / Oxlint (push) Successful in 5m45s
TS Lint / ESLint (push) Successful in 5m52s

This commit is contained in:
2026-07-14 14:21:34 +02:00
parent d380e8baff
commit 9b3c90d6be
+43 -15
View File
@@ -2,7 +2,14 @@
import { ref, onBeforeMount, computed, defineAsyncComponent } from "vue"; import { ref, onBeforeMount, computed, defineAsyncComponent } from "vue";
import type { Task } from "@/types"; import type { Task } from "@/types";
import { getTasks, createTask, deleteTask } from "@/api/tasks"; import { getTasks, createTask, deleteTask } from "@/api/tasks";
import { CirclePlusIcon, ArrowDownUpIcon, Settings2Icon, CircleCheckBigIcon, CheckCheckIcon, SearchIcon } from "@lucide/vue"; import {
CirclePlusIcon,
ArrowDownUpIcon,
Settings2Icon,
CircleCheckBigIcon,
CheckCheckIcon,
SearchIcon,
} from "@lucide/vue";
const TaskItem = defineAsyncComponent( const TaskItem = defineAsyncComponent(
() => import("@/components/TaskItem.vue"), () => import("@/components/TaskItem.vue"),
); );
@@ -11,7 +18,7 @@ import { SortType } from "@/enums";
import { booleanCookieRef, enumCookieRef } from "@/lib/cookies"; import { booleanCookieRef, enumCookieRef } from "@/lib/cookies";
import { useAlertStore } from "@/stores/alerts"; import { useAlertStore } from "@/stores/alerts";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { onBeforeRouteUpdate, useRoute } from 'vue-router' import { onBeforeRouteUpdate, useRoute } from "vue-router";
const route = useRoute(); const route = useRoute();
@@ -19,20 +26,21 @@ const list = ref<string|null>(null);
const taskInput = ref<string>(""); const taskInput = ref<string>("");
const tasks = ref<Task[]>([]); const tasks = ref<Task[]>([]);
const sortType = enumCookieRef<SortType>( const sortType = enumCookieRef<SortType>("sSortType", SortType.CREATED_AT);
"sSortType",
SortType.CREATED_AT,
);
const sortReverse = booleanCookieRef("sortReverse", false); const sortReverse = booleanCookieRef("sortReverse", false);
const showLastChecked = booleanCookieRef("showLastChecked", false); const showLastChecked = booleanCookieRef("showLastChecked", false);
const showNextReset = booleanCookieRef("showNextReset", false); const showNextReset = booleanCookieRef("showNextReset", false);
const separateCompleted = booleanCookieRef("separateCompleted", true); const separateCompleted = booleanCookieRef("separateCompleted", true);
const completedCount = computed<number>(() => tasks.value.filter(taskCompleted).length); const completedCount = computed<number>(
() => tasks.value.filter(taskCompleted).length,
);
const taskCount = computed<number>(() => tasks.value.length); const taskCount = computed<number>(() => tasks.value.length);
const hasCompleted = computed<boolean>(() => completedCount.value > 0); const hasCompleted = computed<boolean>(() => completedCount.value > 0);
const empty = computed<boolean>(() => taskCount.value === 0); const empty = computed<boolean>(() => taskCount.value === 0);
const allCompleted = computed<boolean>(() => taskCount.value === completedCount.value); const allCompleted = computed<boolean>(
() => taskCount.value === completedCount.value,
);
const i18n = useI18n(); const i18n = useI18n();
@@ -124,10 +132,14 @@ onBeforeMount(() => {
onBeforeRouteUpdate((to) => { onBeforeRouteUpdate((to) => {
list.value = to.params.list as string; list.value = to.params.list as string;
fetchTasks(); fetchTasks();
}) });
</script> </script>
<template> <template>
<div class="list-row italic text-sm font-extralight self-center">
{{ list }}
<span v-if="taskCount">({{ completedCount }} / {{ taskCount }})</span>
</div>
<ul class="list"> <ul class="list">
<template v-for="(task, i) in tasks" :key="task.id"> <template v-for="(task, i) in tasks" :key="task.id">
<li v-if="tasks[i] && (!separateCompleted || !taskCompleted(task))"> <li v-if="tasks[i] && (!separateCompleted || !taskCompleted(task))">
@@ -140,14 +152,23 @@ onBeforeRouteUpdate((to) => {
/> />
</li> </li>
</template> </template>
<li v-if="empty" class="list-row italic text-xl font-extralight self-center"> <li
<span><search-icon class="inline" /> <span v-html="$t('empty_hint')"></span></span> v-if="empty"
class="list-row italic text-xl font-extralight self-center"
>
<span
><search-icon class="inline" />
<span v-html="$t('empty_hint')"></span
></span>
</li> </li>
<li <li
v-else-if="allCompleted && separateCompleted" v-else-if="allCompleted && separateCompleted"
class="list-row italic text-xl font-extralight self-center" class="list-row italic text-xl font-extralight self-center"
> >
<span><check-check-icon class="inline" /> <span v-html="$t('all_completed_hint')"></span></span> <span
><check-check-icon class="inline" />
<span v-html="$t('all_completed_hint')"></span
></span>
</li> </li>
<li class="list-row"> <li class="list-row">
<div class="list-col-grow"> <div class="list-col-grow">
@@ -175,7 +196,10 @@ onBeforeRouteUpdate((to) => {
class="collapse collapse-arrow" class="collapse collapse-arrow"
> >
<input id="completed-dropdown" type="checkbox" /> <input id="completed-dropdown" type="checkbox" />
<div class="collapse-title mb-0"><circle-check-big-icon class="inline" :size="24" /> {{ $t("completed") }} ({{ completedCount }})</div> <div class="collapse-title mb-0">
<circle-check-big-icon class="inline" :size="24" />
{{ $t("completed") }} ({{ completedCount }})
</div>
<div class="collapse-content p-0"> <div class="collapse-content p-0">
<ul class="list"> <ul class="list">
<template <template
@@ -197,11 +221,15 @@ onBeforeRouteUpdate((to) => {
</div> </div>
<div class="collapse collapse-arrow font-light text-sm"> <div class="collapse collapse-arrow font-light text-sm">
<input id="options-dropdown" type="checkbox" /> <input id="options-dropdown" type="checkbox" />
<div class="collapse-title"><settings-2-icon class="inline" :size="16" /> {{ $t("options.title") }}</div> <div class="collapse-title">
<settings-2-icon class="inline" :size="16" />
{{ $t("options.title") }}
</div>
<div class="collapse-content"> <div class="collapse-content">
<fieldset class="fieldset flex flex-col gap-2"> <fieldset class="fieldset flex flex-col gap-2">
<label class="label"> <label class="label">
<arrow-down-up-icon class="inline" /> {{ $t("options.sort_by") }} <arrow-down-up-icon class="inline" />
{{ $t("options.sort_by") }}
<select <select
v-model="sortType" v-model="sortType"
class="select" class="select"