From 0f26506d54da674ce6d6f8d0b23c6c906c4bf7a1 Mon Sep 17 00:00:00 2001 From: Ricardo Gonzalez Date: Wed, 27 May 2026 13:46:18 -0500 Subject: [PATCH] agregar endpoint /epicdevelopment/ + store de epicas y HUs por proyecto --- src/services/kappa-api.ts | 16 ++++++++++++ src/services/tauri-db.ts | 22 ++++++++++++++++ src/stores/workitems.ts | 53 +++++++++++++++++++++++++++++++++------ src/types/kappa.ts | 23 +++++++++++++++++ 4 files changed, 106 insertions(+), 8 deletions(-) diff --git a/src/services/kappa-api.ts b/src/services/kappa-api.ts index fc4da2e..a9bbcec 100644 --- a/src/services/kappa-api.ts +++ b/src/services/kappa-api.ts @@ -3,6 +3,7 @@ import type { KappaLoginResponse, KappaInitiative, KappaUserStory, + KappaEpicDevelopment, KappaLogbookMaster, KappaLogbookEntry, KappaPlanningMaster, @@ -103,6 +104,21 @@ class KappaAPI { return this.request('GET', path) } + async getEpicDevelopment(initiativeId: number, page = 1, pageSize = 50): Promise> { + return this.request>('GET', `/epicdevelopment/?initiative=${initiativeId}&page=${page}&page_size=${pageSize}`) + } + + async getAllEpicDevelopment(initiativeId: number): Promise { + const first = await this.getEpicDevelopment(initiativeId, 1, 100) + const all = [...first.results] + const totalPages = Math.ceil(first.count / 100) + for (let p = 2; p <= totalPages; p++) { + const page = await this.getEpicDevelopment(initiativeId, p, 100) + all.push(...page.results) + } + return all + } + async getLogbooks(initiativeId?: number): Promise { const path = initiativeId ? `/logbooks/?initiative=${initiativeId}` : '/logbooks/' return this.request('GET', path) diff --git a/src/services/tauri-db.ts b/src/services/tauri-db.ts index 881119d..d846f3a 100644 --- a/src/services/tauri-db.ts +++ b/src/services/tauri-db.ts @@ -10,6 +10,17 @@ export interface ProjectRecord { end_date: string | null } +export interface WorkItemRecord { + id: number + project_id: number + code: string | null + title: string + description: string | null + type: string + status: string + priority: string +} + export interface AlphaUserRecord { id: number email: string @@ -91,6 +102,17 @@ export const tauriDb = { return invoke('delete_project', { id }) }, + // Work Items + getWorkItems(projectId: number): Promise { + return invoke('get_work_items', { projectId }) + }, + saveWorkItem(item: WorkItemRecord): Promise { + return invoke('save_work_item', { item }) + }, + deleteWorkItem(id: number): Promise { + return invoke('delete_work_item', { id }) + }, + // Users getUsers(): Promise { return invoke('get_users') diff --git a/src/stores/workitems.ts b/src/stores/workitems.ts index 64e150f..e3a48c4 100644 --- a/src/stores/workitems.ts +++ b/src/stores/workitems.ts @@ -1,7 +1,9 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { kappa } from '@/services/kappa-api' -import type { KappaUserStory, KappaLogbookEntry, KappaPlanningEntry } from '@/types/kappa' +import { tauriDb } from '@/services/tauri-db' +import { stripHtml } from '@/services/clean-html' +import type { KappaUserStory, KappaLogbookEntry, KappaPlanningEntry, KappaEpicDevelopment } from '@/types/kappa' export const useWorkItemsStore = defineStore('workitems', () => { const creating = ref(false) @@ -9,13 +11,15 @@ export const useWorkItemsStore = defineStore('workitems', () => { const error = ref(null) const userStories = ref([]) + const epics = ref([]) const logbooks = ref([]) const plannings = ref([]) const totalHUs = computed(() => userStories.value.length) + const totalEpics = computed(() => epics.value.length) const inProgressHUs = computed(() => - userStories.value.filter(us => - us.status && ['in_progress', 'doing', 'wip', 'active'].includes(us.status.toLowerCase()) + userStories.value.filter(hu => + hu.status && ['in_progress', 'doing', 'wip', 'active', 'in progress'].includes(hu.status.toLowerCase()) ).length ) const totalSessions = computed(() => logbooks.value.length) @@ -38,18 +42,34 @@ export const useWorkItemsStore = defineStore('workitems', () => { async function fetchWorkItems(initiativeId?: number) { loading.value = true error.value = null + + const id = initiativeId || Number(localStorage.getItem('kappa_last_project')) + if (!id) { + loading.value = false + return + } + try { - const [stories, logs, plans] = await Promise.all([ - kappa.getUserStories(initiativeId), - kappa.getLogbooks(initiativeId), - kappa.getPlannings(initiativeId), + const [stories, logs, plans, epicData] = await Promise.all([ + kappa.getUserStories(id).catch(() => [] as KappaUserStory[]), + kappa.getLogbooks(id).catch(() => [] as KappaLogbookEntry[]), + kappa.getPlannings(id).catch(() => [] as KappaPlanningEntry[]), + kappa.getAllEpicDevelopment(id).catch(() => [] as KappaEpicDevelopment[]), ]) + const storiesData = stories as KappaUserStory[] | { results?: KappaUserStory[] } const logsData = logs as KappaLogbookEntry[] | { results?: KappaLogbookEntry[] } const plansData = plans as KappaPlanningEntry[] | { results?: KappaPlanningEntry[] } userStories.value = Array.isArray(storiesData) ? storiesData : (storiesData.results ?? []) logbooks.value = Array.isArray(logsData) ? logsData : (logsData.results ?? []) plannings.value = Array.isArray(plansData) ? plansData : (plansData.results ?? []) + + epics.value = epicData.map(epic => ({ + ...epic, + description: stripHtml(epic.description || ''), + })) + + syncHUsToTurso(id, userStories.value) } catch (e: any) { error.value = e.message } finally { @@ -57,17 +77,34 @@ export const useWorkItemsStore = defineStore('workitems', () => { } } + async function syncHUsToTurso(projectId: number, hus: KappaUserStory[]) { + for (const hu of hus) { + await tauriDb.saveWorkItem({ + id: hu.id ?? 0, + project_id: projectId, + code: hu.code ?? null, + title: hu.title, + description: stripHtml(hu.description || ''), + type: 'hu', + status: hu.status || 'backlog', + priority: hu.priority || 'medium', + }).catch(() => {}) + } + } + return { creating, loading, error, userStories, + epics, logbooks, plannings, totalHUs, + totalEpics, inProgressHUs, totalSessions, createUserStory, fetchWorkItems, } -}) \ No newline at end of file +}) diff --git a/src/types/kappa.ts b/src/types/kappa.ts index 93d16d7..107b42b 100644 --- a/src/types/kappa.ts +++ b/src/types/kappa.ts @@ -48,6 +48,29 @@ export interface KappaUserStory { created_at?: string } +export interface KappaEpicDevelopment { + id: number + code?: string + title?: string + name?: string + description?: string + status?: string + priority?: string + initiative?: number + initiative_name?: string + initiative_key?: string + assigned_to?: number | null + assigned_name?: string + story_points?: number + estimated_hours?: number + actual_hours?: number + start_date?: string + due_date?: string + completed_date?: string + created_at?: string + updated_at?: string +} + export interface KappaLogbookMaster { id?: number initiative: number | string