import { defineStore } from 'pinia' import { ref } from 'vue' import { type CreateIssueInput, type Issue, type DailyIssueStats, itemCreate, itemDailyStat, itemDelete, itemGetByKey, itemsList, itemStat, itemUpdate, type IssueStat, type Meta, type UpdateIssueInput, } from '@/api/issue.api.ts' export const useIssueStore = defineStore('item', () => { const issues = ref([]) const stats = ref() const dailyStats = ref() const error = ref(null) const lastMeta = ref({ page: 1, totalCount: 0, totalPages: 0, }) async function list(params: { page: number limit: number text?: string | null status?: string | string[] | null assigneeId?: string | null projectId?: string | null }) { try { const res = await itemsList(params) issues.value = res.list return res } catch (e) { error.value = e instanceof Error ? e.message : 'error get list of items' return { list: [], meta: lastMeta.value } } } async function getByKey(ckey: string) { try { return await itemGetByKey(ckey) } catch (e) { error.value = e instanceof Error ? e.message : 'error get item by key' } } async function create(input: CreateIssueInput) { try { return await itemCreate(input) } catch (e) { error.value = e instanceof Error ? e.message : 'error creating issue' } } async function update(id: number, input: UpdateIssueInput) { try { return await itemUpdate(id, input) } catch (e) { error.value = e instanceof Error ? e.message : 'error updating issue' } } async function remove(id: number) { try { return await itemDelete(id) } catch (e) { error.value = e instanceof Error ? e.message : 'error deleting issue' return false } } async function getStat(projectId?: string | null): Promise { try { stats.value = await itemStat(projectId ?? undefined) return stats.value } catch (e) { error.value = e instanceof Error ? e.message : 'error getting issue stat' } } let dailyStatsRequestId = 0 /** Stats for the last `days` days including today, in the user's local time zone */ async function getDailyStat(projectId?: string | null, days = 30): Promise { // Ignore responses that arrive after the project or period has changed again const requestId = ++dailyStatsRequestId try { const res = await itemDailyStat({ projectId: projectId ?? undefined, from: localDateDaysAgo(days - 1), // Day boundaries are computed on the backend in the user's local time zone; `to` defaults to today there timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone, }) if (requestId !== dailyStatsRequestId) return dailyStats.value = res return dailyStats.value } catch (e) { error.value = e instanceof Error ? e.message : 'error getting daily issue stat' } } return { stats, dailyStats, list, getByKey, create, update, remove, getStat, getDailyStat } }) /** Local YYYY-MM-DD `days` days before today */ function localDateDaysAgo(days: number): string { const date = new Date() date.setDate(date.getDate() - days) const pad = (value: number) => String(value).padStart(2, '0') return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` }