feat(time-tracking) : add TimeEntry DTO, service, timer store, and i18n keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import type { TaskPriority } from './task-priority'
|
||||
import type { TaskType } from './task-type'
|
||||
import type { TaskGroup } from './task-group'
|
||||
import type { UserData } from './user-data'
|
||||
import type { Project } from './project'
|
||||
|
||||
export type Task = {
|
||||
id: number
|
||||
@@ -15,6 +16,7 @@ export type Task = {
|
||||
priority: TaskPriority | null
|
||||
assignee: UserData | null
|
||||
group: TaskGroup | null
|
||||
project: Project | null
|
||||
types: TaskType[]
|
||||
}
|
||||
|
||||
|
||||
28
frontend/services/dto/time-entry.ts
Normal file
28
frontend/services/dto/time-entry.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { UserData } from './user-data'
|
||||
import type { Project } from './project'
|
||||
import type { Task } from './task'
|
||||
import type { TaskType } from './task-type'
|
||||
|
||||
export type TimeEntry = {
|
||||
id: number
|
||||
'@id'?: string
|
||||
title: string | null
|
||||
description: string | null
|
||||
startedAt: string
|
||||
stoppedAt: string | null
|
||||
user: UserData
|
||||
project: Project | null
|
||||
task: Task | null
|
||||
types: TaskType[]
|
||||
}
|
||||
|
||||
export type TimeEntryWrite = {
|
||||
title?: string | null
|
||||
description?: string | null
|
||||
startedAt: string
|
||||
stoppedAt?: string | null
|
||||
user: string
|
||||
project?: string | null
|
||||
task?: string | null
|
||||
types?: string[]
|
||||
}
|
||||
53
frontend/services/time-entries.ts
Normal file
53
frontend/services/time-entries.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import type { TimeEntry, TimeEntryWrite } from './dto/time-entry'
|
||||
import type { HydraCollection } from '~/utils/api'
|
||||
import { extractHydraMembers } from '~/utils/api'
|
||||
|
||||
export function useTimeEntryService() {
|
||||
const api = useApi()
|
||||
|
||||
async function getByDateRange(params: {
|
||||
after: string
|
||||
before: string
|
||||
user?: number
|
||||
types?: number[]
|
||||
}): Promise<TimeEntry[]> {
|
||||
const query: Record<string, unknown> = {
|
||||
'startedAt[after]': params.after,
|
||||
'startedAt[before]': params.before,
|
||||
}
|
||||
if (params.user) {
|
||||
query.user = `/api/users/${params.user}`
|
||||
}
|
||||
const data = await api.get<HydraCollection<TimeEntry>>('/time_entries', query)
|
||||
return extractHydraMembers(data)
|
||||
}
|
||||
|
||||
async function getActive(): Promise<TimeEntry | null> {
|
||||
try {
|
||||
const result = await api.get<TimeEntry | null>('/time_entries/active', {}, { toast: false })
|
||||
return result ?? null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function create(payload: TimeEntryWrite): Promise<TimeEntry> {
|
||||
return api.post<TimeEntry>('/time_entries', payload as Record<string, unknown>, {
|
||||
toastSuccessKey: 'timeEntries.created',
|
||||
})
|
||||
}
|
||||
|
||||
async function update(id: number, payload: Partial<TimeEntryWrite>): Promise<TimeEntry> {
|
||||
return api.patch<TimeEntry>(`/time_entries/${id}`, payload as Record<string, unknown>, {
|
||||
toastSuccessKey: 'timeEntries.updated',
|
||||
})
|
||||
}
|
||||
|
||||
async function remove(id: number): Promise<void> {
|
||||
await api.delete(`/time_entries/${id}`, {}, {
|
||||
toastSuccessKey: 'timeEntries.deleted',
|
||||
})
|
||||
}
|
||||
|
||||
return { getByDateRange, getActive, create, update, remove }
|
||||
}
|
||||
Reference in New Issue
Block a user