feat: show missed tasks

This commit is contained in:
2026-07-21 11:19:37 +02:00
parent 6f8c14e8fb
commit 0abcc7ae1b
8 changed files with 144 additions and 89 deletions
+97
View File
@@ -0,0 +1,97 @@
<script setup lang="ts">
import { ArrowDownUpIcon, Settings2Icon } from "@lucide/vue";
import { SortType } from "@/enums";
defineEmits<(e: "changeSort") => void>();
const sortType = defineModel<SortType>("sortType", { required: true });
const sortReverse = defineModel<boolean>("sortReverse", { required: true });
const showLastChecked = defineModel<boolean>("showLastChecked", {
required: true,
});
const showNextReset = defineModel<boolean>("showNextReset", { required: true });
const separateCompleted = defineModel<boolean>("separateCompleted", {
required: true,
});
const showMissed = defineModel<boolean>("showMissed", { required: true });
</script>
<template>
<div class="collapse collapse-arrow font-light text-sm">
<input id="options-dropdown p-0" type="checkbox" />
<div class="collapse-title p-0 content-center">
<settings-2-icon class="inline" :size="16" />
{{ $t("options.title") }}
</div>
<div class="collapse-content">
<div class="w-full flex flex-col gap-2 text-left overflow-scroll">
<label class="label">
<arrow-down-up-icon class="inline" />
{{ $t("options.sort_by") }}
<select
v-model="sortType"
class="select"
@change="$emit('changeSort')"
>
<option :value="SortType.CREATED_AT">
{{ $t("options.sort.created_at") }}
</option>
<option :value="SortType.UPDATED_AT">
{{ $t("options.sort.updated_at") }}
</option>
<option :value="SortType.CHECK_DATE">
{{ $t("options.sort.check_date") }}
</option>
<option :value="SortType.RESET_DATE">
{{ $t("options.sort.reset_date") }}
</option>
<option :value="SortType.NAME">
{{ $t("options.sort.name") }}
</option>
</select>
</label>
<label class="label text-wrap">
<input
v-model="sortReverse"
type="checkbox"
class="checkbox"
@change="$emit('changeSort')"
/>
{{ $t("options.reverse_sort") }}
</label>
<label class="label text-wrap">
<input
v-model="showLastChecked"
type="checkbox"
class="checkbox"
/>
{{ $t("options.last_checked") }}
</label>
<label class="label text-wrap">
<input
v-model="showNextReset"
type="checkbox"
class="checkbox"
/>
{{ $t("options.next_reset") }}
</label>
<label class="label text-wrap">
<input
v-model="separateCompleted"
type="checkbox"
class="checkbox"
/>
{{ $t("options.separate_completed") }}
</label>
<label class="label text-wrap">
<input
v-model="showMissed"
type="checkbox"
class="checkbox"
/>
{{ $t("options.missed") }}
</label>
</div>
</div>
</div>
</template>
+19 -2
View File
@@ -13,7 +13,12 @@ import { updateTask } from "@/api/tasks";
const CronInput = defineAsyncComponent(
() => import("@/components/CronInput.vue"),
);
import { isTemporary, taskCompleted, taskNextReset } from "@/lib/tasks";
import {
isTemporary,
taskCompleted,
taskFutureReset,
taskNextReset,
} from "@/lib/tasks";
import { relativeTime } from "@/lib/dates";
import { useAlertStore } from "@/stores/alerts";
import { useI18n } from "vue-i18n";
@@ -23,7 +28,11 @@ const emit =
defineEmits<(e: "clone" | "delete" | "updated", task: Task) => void>();
const task = defineModel<Task>({ required: true });
defineProps<{ showLastChecked: boolean; showNextReset: boolean }>();
defineProps<{
showLastChecked: boolean;
showNextReset: boolean;
showMissed: boolean;
}>();
const editMode = ref<boolean>(false);
const editName = ref<string>("");
@@ -33,6 +42,13 @@ const editNameInput = ref<HTMLInputElement | null>(null);
const checked = computed<boolean>(() => taskCompleted(task.value));
const nextReset = computed<Date | null>(() => taskNextReset(task.value));
const futureReset = computed<Date | null>(() => taskFutureReset(task.value));
const missed = computed<boolean>(
() =>
!checked.value &&
futureReset.value !== null &&
futureReset.value.getTime() < new Date().getTime(),
);
const i18n = useI18n();
@@ -157,6 +173,7 @@ watch(task, () => {
</div>
<div
class="cursor-pointer text-lg select-none"
:class="showMissed && missed ? 'text-error' : ''"
@click.prevent="onOpen"
>
<div>{{ task.name }}</div>