118 lines
2.9 KiB
TypeScript
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}`)
|
|
}
|