From a656112488fe33bb9c3e486ac01632f76e796b95 Mon Sep 17 00:00:00 2001 From: Nick Kosarev Date: Fri, 17 Oct 2025 14:52:56 +0200 Subject: [PATCH 1/2] feat: flow mode for tasks --- apps/atrium-telegram/app/pages/task/my.vue | 63 ++++++++++++++----- apps/atrium-telegram/app/stores/task.ts | 40 ++++++++++++ .../server/api/task/list/not-completed.get.ts | 5 ++ packages/database/src/repository/task.ts | 7 +++ 4 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 apps/atrium-telegram/server/api/task/list/not-completed.get.ts diff --git a/apps/atrium-telegram/app/pages/task/my.vue b/apps/atrium-telegram/app/pages/task/my.vue index 573f4247..6cf59105 100644 --- a/apps/atrium-telegram/app/pages/task/my.vue +++ b/apps/atrium-telegram/app/pages/task/my.vue @@ -12,7 +12,10 @@ :class="[ taskStore.isTodayOnly ? 'tg-text' : 'text-secondary', ]" - @click="taskStore.isTodayOnly = !taskStore.isTodayOnly" + @click="() => { + taskStore.isTodayOnly = !taskStore.isTodayOnly + taskStore.isInFlowMode = false + }" > {{ taskStore.myTodayTasks.length }} {{ pluralizationRu(taskStore.myTodayTasks.length, ['задача', 'задачи', 'задач']) }} . @@ -26,22 +29,52 @@
@@ -58,6 +91,8 @@ definePageMeta({ name: 'my-tasks', }) +const { vibrate } = useFeedback() + const overlay = useOverlay() const modalCreateTaskList = overlay.create(ModalCreateTaskList) diff --git a/apps/atrium-telegram/app/stores/task.ts b/apps/atrium-telegram/app/stores/task.ts index 2d5d1697..2bb3bbfa 100644 --- a/apps/atrium-telegram/app/stores/task.ts +++ b/apps/atrium-telegram/app/stores/task.ts @@ -14,7 +14,9 @@ type TaskListWithData = TaskList & { export const useTaskStore = defineStore('task', () => { const lists = ref([]) const tasks = ref([]) + const notCompletedTasks = ref([]) const isTodayOnly = ref(false) + const isInFlowMode = ref(false) const isInitialized = ref(false) const userStore = useUserStore() @@ -25,6 +27,16 @@ export const useTaskStore = defineStore('task', () => { ).filter((taskList) => isTodayOnly.value ? taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone())).length : true), ) const myTodayTasks = computed(() => myLists.value.flatMap((taskList) => taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone())))) + const myTasksOrderedByDate = computed(() => { + const filterByMe = (task: Task) => task.performerId === userStore.id + const sortByDateAsc = (a: Task, b: Task) => a.date && b.date ? new Date(a.date).getTime() - new Date(b.date).getTime() : 0 + + const myTasks = notCompletedTasks.value.filter(filterByMe) + const tasksWithDate = myTasks.filter((task) => task.date).sort(sortByDateAsc) + const tasksWithoutDate = myTasks.filter((task) => !task.date) + + return [...tasksWithDate, ...tasksWithoutDate] + }) const initDataRaw = useSignal(_initDataRaw) @@ -44,6 +56,7 @@ export const useTaskStore = defineStore('task', () => { isInitialized.value = true await updateCompleted() + await updateNotCompleted() } catch (error) { if (error instanceof Error) { if (error.message.includes('401')) { @@ -80,6 +93,30 @@ export const useTaskStore = defineStore('task', () => { } } + async function updateNotCompleted() { + try { + const data = await $fetch('/api/task/list/not-completed', { + headers: { + Authorization: `tma ${initDataRaw.value}`, + }, + }) + if (!data) { + return + } + + notCompletedTasks.value = data + } catch (error) { + if (error instanceof Error) { + if (error.message.includes('401')) { + // No session + } + if (error.message.includes('404')) { + // Not found + } + } + } + } + async function setAsFocused(taskId: string) { try { await $fetch(`/api/task/id/${taskId}/focus`, { @@ -117,11 +154,14 @@ export const useTaskStore = defineStore('task', () => { return { lists, tasks, + notCompletedTasks, isTodayOnly, + isInFlowMode, isInitialized, myLists, myTodayTasks, + myTasksOrderedByDate, update, setAsFocused, diff --git a/apps/atrium-telegram/server/api/task/list/not-completed.get.ts b/apps/atrium-telegram/server/api/task/list/not-completed.get.ts new file mode 100644 index 00000000..e7aa1722 --- /dev/null +++ b/apps/atrium-telegram/server/api/task/list/not-completed.get.ts @@ -0,0 +1,5 @@ +import { db } from '@roll-stack/database' + +export default defineEventHandler(async () => { + return db.task.findAllNotCompleted() +}) diff --git a/packages/database/src/repository/task.ts b/packages/database/src/repository/task.ts index fc1a1286..86447ef3 100644 --- a/packages/database/src/repository/task.ts +++ b/packages/database/src/repository/task.ts @@ -17,6 +17,13 @@ export class Task { }) } + static async findAllNotCompleted() { + return useDatabase().query.tasks.findMany({ + where: (tasks, { isNull }) => isNull(tasks.completedAt), + orderBy: (tasks, { desc }) => desc(tasks.updatedAt), + }) + } + static async findList(id: string) { return useDatabase().query.taskLists.findFirst({ where: (taskLists, { eq, and }) => and(eq(taskLists.id, id), eq(taskLists.isArchived, false)), From c9b9b26e5bbfb56ad05f834d782208bd5d8ee793 Mon Sep 17 00:00:00 2001 From: Nick Kosarev Date: Fri, 17 Oct 2025 14:57:27 +0200 Subject: [PATCH 2/2] chore: update --- apps/atrium-telegram/app/pages/task/[taskId]/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/atrium-telegram/app/pages/task/[taskId]/index.vue b/apps/atrium-telegram/app/pages/task/[taskId]/index.vue index 41a4f012..b5139ace 100644 --- a/apps/atrium-telegram/app/pages/task/[taskId]/index.vue +++ b/apps/atrium-telegram/app/pages/task/[taskId]/index.vue @@ -57,7 +57,7 @@

-
+
Создана