Skip to content

Commit dff39c1

Browse files
authored
feat: flow mode for tasks (#230)
* feat: flow mode for tasks * chore: update
1 parent 217b76e commit dff39c1

5 files changed

Lines changed: 102 additions & 15 deletions

File tree

apps/atrium-telegram/app/pages/task/[taskId]/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
</p>
5858
</div>
5959

60-
<div class="mt-6 flex flex-col gap-0.5">
60+
<div class="mt-6 flex flex-col gap-1">
6161
<div class="text-sm text-muted">
6262
Создана
6363
<time

apps/atrium-telegram/app/pages/task/my.vue

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
:class="[
1313
taskStore.isTodayOnly ? 'tg-text' : 'text-secondary',
1414
]"
15-
@click="taskStore.isTodayOnly = !taskStore.isTodayOnly"
15+
@click="() => {
16+
taskStore.isTodayOnly = !taskStore.isTodayOnly
17+
taskStore.isInFlowMode = false
18+
}"
1619
>
1720
{{ taskStore.myTodayTasks.length }} {{ pluralizationRu(taskStore.myTodayTasks.length, ['задача', 'задачи', 'задач']) }}
1821
</ULink>.
@@ -26,22 +29,52 @@
2629

2730
<template v-if="taskStore.isInitialized">
2831
<Section>
29-
<TasksTodaySwitch />
32+
<USwitch
33+
v-model="taskStore.isInFlowMode"
34+
size="xl"
35+
color="secondary"
36+
:label="taskStore.isInFlowMode ? `Режим &quot;Поток&quot;` : 'Режим &quot;Списки&quot;'"
37+
:ui="{
38+
root: 'items-center',
39+
label: 'ml-1.5 text-base/5 font-semibold',
40+
}"
41+
@change="vibrate()"
42+
/>
3043
</Section>
3144

32-
<TaskList
33-
v-for="taskList in taskStore.myLists"
34-
:key="taskList.id"
35-
:list-id="taskList.id"
36-
:current-user-id="userStore.id as string"
37-
/>
45+
<div v-if="!taskStore.isInFlowMode" class="flex flex-col gap-8">
46+
<TaskList
47+
v-for="taskList in taskStore.myLists"
48+
:key="taskList.id"
49+
:list-id="taskList.id"
50+
:current-user-id="userStore.id as string"
51+
/>
3852

39-
<CreateCard
40-
v-if="!taskStore.isTodayOnly"
41-
:label="$t('app.create.task-list.button')"
42-
icon="i-lucide-list-todo"
43-
@click="modalCreateTaskList.open()"
44-
/>
53+
<CreateCard
54+
v-if="!taskStore.isTodayOnly"
55+
:label="$t('app.create.task-list.button')"
56+
icon="i-lucide-list-todo"
57+
@click="modalCreateTaskList.open()"
58+
/>
59+
</div>
60+
61+
<div v-else>
62+
<div
63+
v-if="taskStore.myTasksOrderedByDate.length"
64+
class="w-full flex flex-col gap-2.5"
65+
>
66+
<TaskActiveCard
67+
v-for="task in taskStore.myTasksOrderedByDate"
68+
:key="task.id"
69+
:task="task"
70+
/>
71+
</div>
72+
<template v-else>
73+
<p class="text-center text-base text-muted">
74+
Активных задач нет
75+
</p>
76+
</template>
77+
</div>
4578
</template>
4679
<div v-else>
4780
<div class="py-4 w-full flex justify-center">
@@ -58,6 +91,8 @@ definePageMeta({
5891
name: 'my-tasks',
5992
})
6093
94+
const { vibrate } = useFeedback()
95+
6196
const overlay = useOverlay()
6297
const modalCreateTaskList = overlay.create(ModalCreateTaskList)
6398

apps/atrium-telegram/app/stores/task.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ type TaskListWithData = TaskList & {
1414
export const useTaskStore = defineStore('task', () => {
1515
const lists = ref<TaskListWithData[]>([])
1616
const tasks = ref<Task[]>([])
17+
const notCompletedTasks = ref<Task[]>([])
1718
const isTodayOnly = ref(false)
19+
const isInFlowMode = ref(false)
1820
const isInitialized = ref(false)
1921

2022
const userStore = useUserStore()
@@ -25,6 +27,16 @@ export const useTaskStore = defineStore('task', () => {
2527
).filter((taskList) => isTodayOnly.value ? taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone())).length : true),
2628
)
2729
const myTodayTasks = computed(() => myLists.value.flatMap((taskList) => taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone()))))
30+
const myTasksOrderedByDate = computed(() => {
31+
const filterByMe = (task: Task) => task.performerId === userStore.id
32+
const sortByDateAsc = (a: Task, b: Task) => a.date && b.date ? new Date(a.date).getTime() - new Date(b.date).getTime() : 0
33+
34+
const myTasks = notCompletedTasks.value.filter(filterByMe)
35+
const tasksWithDate = myTasks.filter((task) => task.date).sort(sortByDateAsc)
36+
const tasksWithoutDate = myTasks.filter((task) => !task.date)
37+
38+
return [...tasksWithDate, ...tasksWithoutDate]
39+
})
2840

2941
const initDataRaw = useSignal(_initDataRaw)
3042

@@ -44,6 +56,7 @@ export const useTaskStore = defineStore('task', () => {
4456
isInitialized.value = true
4557

4658
await updateCompleted()
59+
await updateNotCompleted()
4760
} catch (error) {
4861
if (error instanceof Error) {
4962
if (error.message.includes('401')) {
@@ -80,6 +93,30 @@ export const useTaskStore = defineStore('task', () => {
8093
}
8194
}
8295

96+
async function updateNotCompleted() {
97+
try {
98+
const data = await $fetch('/api/task/list/not-completed', {
99+
headers: {
100+
Authorization: `tma ${initDataRaw.value}`,
101+
},
102+
})
103+
if (!data) {
104+
return
105+
}
106+
107+
notCompletedTasks.value = data
108+
} catch (error) {
109+
if (error instanceof Error) {
110+
if (error.message.includes('401')) {
111+
// No session
112+
}
113+
if (error.message.includes('404')) {
114+
// Not found
115+
}
116+
}
117+
}
118+
}
119+
83120
async function setAsFocused(taskId: string) {
84121
try {
85122
await $fetch(`/api/task/id/${taskId}/focus`, {
@@ -117,11 +154,14 @@ export const useTaskStore = defineStore('task', () => {
117154
return {
118155
lists,
119156
tasks,
157+
notCompletedTasks,
120158
isTodayOnly,
159+
isInFlowMode,
121160
isInitialized,
122161

123162
myLists,
124163
myTodayTasks,
164+
myTasksOrderedByDate,
125165

126166
update,
127167
setAsFocused,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { db } from '@roll-stack/database'
2+
3+
export default defineEventHandler(async () => {
4+
return db.task.findAllNotCompleted()
5+
})

packages/database/src/repository/task.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ export class Task {
1717
})
1818
}
1919

20+
static async findAllNotCompleted() {
21+
return useDatabase().query.tasks.findMany({
22+
where: (tasks, { isNull }) => isNull(tasks.completedAt),
23+
orderBy: (tasks, { desc }) => desc(tasks.updatedAt),
24+
})
25+
}
26+
2027
static async findList(id: string) {
2128
return useDatabase().query.taskLists.findFirst({
2229
where: (taskLists, { eq, and }) => and(eq(taskLists.id, id), eq(taskLists.isArchived, false)),

0 commit comments

Comments
 (0)