Add HelpPanel and TodoItemTouch components, extend task commands, and refactor task and view logic

- Introduced `HelpPanel.vue` for displaying keyboard shortcuts and command descriptions.
- Added `TodoItemTouch.vue`, a mobile-friendly task item component with updated bindings and improved actions.
- Extended task commands with support for tagging, due date parsing, and dynamic text formatting.
- Implemented `useActions` utility for parsing and executing command-based task modifications.
- Streamlined task editing and creation in `useTasks` for consistency and API integration.
- Updated `ListScreen` to support collapsible, categorized task lists with visual enhancements.
- Refactored `App.vue` for adaptive input handling on mobile versus desktop views.
- Enhanced API communication in `useApi` with cleaner header generation and error handling.
This commit is contained in:
2026-02-23 16:34:52 +01:00
parent ec76a52fdd
commit 56f89b6669
21 changed files with 1347 additions and 214 deletions

View File

@@ -1,6 +1,7 @@
import type { Task } from '../types.ts'
import { useArrayUnique } from '@vueuse/core'
import { ref } from 'vue'
import { TaskStatus } from '../types.ts'
import { useApi } from './useApi.ts'
const tasks = ref<Task[]>([])
@@ -29,22 +30,23 @@ export function useTasks() {
}
}
const createTask = async (taskData: Partial<Task>) => {
const createTask = async (taskData: Pick<Task, 'title' | 'dueDate' | 'tag'>) => {
// Get next ID as per current logic in CreateScreen.vue
const nextId = () => tasks.value.sort((a, b) => a.id_ - b.id_).reduce((acc, task) => {
if (task.id_ === acc + 1)
return acc + 1
return acc
}, 0) + 1
isLoading.value = true
error.value = null
try {
// Get next ID as per current logic in CreateScreen.vue
const nextId = tasks.value.sort((a, b) => b.id_ - a.id_).reduce((acc, task) => {
if (task.id_ === acc + 1)
return acc + 1
return task.id_ + 1
}, 0)
const newTask: Partial<Task> = {
...taskData,
id_: nextId,
const newTask: Omit<Task, 'id'> = {
id_: nextId(),
status: TaskStatus.WAIT,
logs: [],
lastaction: Date.now(),
archived: false,
...taskData,
}
const data = await api.put('e5880167-9322-4d7b-8a38-e06bae8a7734/list', { tasks: [newTask] }).then(res => res.json())
@@ -62,12 +64,12 @@ export function useTasks() {
}
}
const updateTask = async (task: Task) => {
console.log('updateTask', task)
const updateTask = async (task: Task | Task[]) => {
isLoading.value = true
error.value = null
const tasksToUpdate = (Array.isArray(task) ? task : [task]).map(t => ({ ...t, lastaction: Date.now() } as Task))
try {
const data = await api.put('e5880167-9322-4d7b-8a38-e06bae8a7734/list', { tasks: [task] }).then(res => res.json())
const data = await api.put('e5880167-9322-4d7b-8a38-e06bae8a7734/list', { tasks: tasksToUpdate }).then(res => res.json())
if (data.tasks) {
tasks.value = data.tasks
}