diff --git a/src/api/issue.api.ts b/src/api/issue.api.ts index 12e7e8c..255b58c 100644 --- a/src/api/issue.api.ts +++ b/src/api/issue.api.ts @@ -68,6 +68,12 @@ export interface DailyIssueStats { days: DailyIssueStat[] } +export interface CalendarIssues { + list: Issue[] + /** The range holds more issues than returned — narrow the filter */ + truncated: boolean +} + // CLIENT REQUEST export async function itemsList(params: { @@ -77,6 +83,7 @@ export async function itemsList(params: { status?: string | string[] | null assigneeId?: string | null projectId?: string | null + hasDueDate?: boolean }) { const query = toQuery({ page: params.page, @@ -85,10 +92,29 @@ export async function itemsList(params: { text: params.text, assigneeId: params.assigneeId, status: Array.isArray(params.status) ? params.status.join(',') : params.status, + hasDueDate: params.hasDueDate === undefined ? undefined : String(params.hasDueDate), }) return apiClient.get<{ list: Issue[]; meta: Meta }>(`/api/issues/list${query}`) } +/** Issues with dueDate in [from, to); from/to are ISO moments with an offset */ +export async function itemsCalendar(params: { + from: string + to: string + projectId?: string | null + assigneeId?: string | null + status?: string[] | null +}) { + const query = toQuery({ + from: params.from, + to: params.to, + projectId: params.projectId, + assigneeId: params.assigneeId, + status: params.status?.join(','), + }) + return apiClient.get(`/api/issues/calendar${query}`) +} + export async function itemGetByKey(ckey: string) { return apiClient.get(`/api/issues/by-key/${ckey}`) } diff --git a/src/components/BackButton.vue b/src/components/BackButton.vue index 0949067..fded4dd 100644 --- a/src/components/BackButton.vue +++ b/src/components/BackButton.vue @@ -10,7 +10,10 @@ const backTo = computed(() => { }) function goBack() { - if (backTo.value) router.push({ name: backTo.value }) + // vue-router keeps the previous in-app location in history.state.back; + // it's null when the page was opened directly, so fall back to backTo + if (window.history.state?.back) router.back() + else if (backTo.value) router.push({ name: backTo.value }) } diff --git a/src/stores/issue.ts b/src/stores/issue.ts index d7d0f13..62c6417 100644 --- a/src/stores/issue.ts +++ b/src/stores/issue.ts @@ -6,6 +6,7 @@ import { type DailyIssueStats, itemCreate, itemDailyStat, + itemsCalendar, itemDelete, itemGetByKey, itemsList, @@ -34,6 +35,7 @@ export const useIssueStore = defineStore('item', () => { status?: string | string[] | null assigneeId?: string | null projectId?: string | null + hasDueDate?: boolean }) { try { const res = await itemsList(params) @@ -45,6 +47,14 @@ export const useIssueStore = defineStore('item', () => { } } + async function calendar(params: { from: string; to: string; projectId?: string | null }) { + try { + return await itemsCalendar(params) + } catch (e) { + error.value = e instanceof Error ? e.message : 'error get calendar issues' + } + } + async function getByKey(ckey: string) { try { return await itemGetByKey(ckey) @@ -110,7 +120,7 @@ export const useIssueStore = defineStore('item', () => { } } - return { stats, dailyStats, list, getByKey, create, update, remove, getStat, getDailyStat } + return { stats, dailyStats, list, calendar, getByKey, create, update, remove, getStat, getDailyStat } }) /** Local YYYY-MM-DD `days` days before today */ diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index 8b96060..84690b2 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -153,8 +153,6 @@ function onClickCard(status?: string) { - - diff --git a/src/views/calendar/CalendarView.vue b/src/views/calendar/CalendarView.vue index ec8f6a8..cd2abc2 100644 --- a/src/views/calendar/CalendarView.vue +++ b/src/views/calendar/CalendarView.vue @@ -1,54 +1,438 @@ - + +