Files
ulitka-app/src/api/issue.api.ts
T
vadim 4caaf74b9f
Gitea Actions Demo / Deploy (push) Successful in 25s
chart bar
2026-10-08 14:06:15 +03:00

118 lines
2.9 KiB
TypeScript

import { apiClient, toQuery } from '@/lib/api-client.ts'
import type { User } from '@/api/user.api.ts'
export interface Issue {
id: number
key: string
title: string
content: string
status: 'OPEN' | 'IN_PROGRESS' | 'DONE' | 'CANCELLED'
priority: 0 | 1 | 2 | 3 | 4
assigneeId: string
reporterId: string
assignee?: User
reporter?: User
dueDate: string | null
createdAt: string
updatedAt: string
}
export interface Meta {
page: number
totalCount: number
totalPages: number
}
export interface CreateIssueInput {
key: string
title: string
projectId: string
content?: string
status?: Issue['status']
priority?: Issue['priority']
assignee?: string
dueDate?: string | null
}
export type UpdateIssueInput = Partial<CreateIssueInput>
export interface IssueStatByStatus {
status: Issue['status']
label: string
count: number
}
export interface IssueStat {
total: number
byStatus: IssueStatByStatus[]
}
/** Count per issue status; statuses without issues are 0 */
export type IssueStatusCounts = Record<Issue['status'], number>
export interface DailyIssueStat {
/** YYYY-MM-DD in the requested time zone */
date: string
/** Issues created during the day */
created: number
/** Transitions into each status during the day (creation into OPEN is not included) */
transitions: IssueStatusCounts
/** Issues in each status at the end of the day */
byStatus: IssueStatusCounts
}
export interface DailyIssueStats {
from: string
to: string
timeZone: string
days: DailyIssueStat[]
}
// CLIENT REQUEST
export async function itemsList(params: {
page: number
limit: number
text?: string | null
status?: string | string[] | null
assigneeId?: string | null
projectId?: string | null
}) {
const query = toQuery({
page: params.page,
limit: params.limit,
projectId: params.projectId,
text: params.text,
assigneeId: params.assigneeId,
status: Array.isArray(params.status) ? params.status.join(',') : params.status,
})
return apiClient.get<{ list: Issue[]; meta: Meta }>(`/api/issues/list${query}`)
}
export async function itemGetByKey(ckey: string) {
return apiClient.get<Issue>(`/api/issues/by-key/${ckey}`)
}
export async function itemCreate(input: CreateIssueInput) {
return apiClient.post<Issue>('/api/issues', input)
}
export async function itemUpdate(id: number, input: UpdateIssueInput) {
return apiClient.patch<Issue>(`/api/issues/${id}`, input)
}
export async function itemDelete(id: number) {
await apiClient.delete(`/api/issues/${id}`)
return true
}
export async function itemStat(projectId?: string) {
const query = toQuery({ projectId: projectId })
return apiClient.get<IssueStat>(`/api/issues/stats${query}`)
}
export async function itemDailyStat(params: { projectId?: string; from?: string; to?: string; timeZone?: string }) {
const query = toQuery(params)
return apiClient.get<DailyIssueStats>(`/api/issues/stats/daily${query}`)
}