diff --git a/src/services/clean-html.ts b/src/services/clean-html.ts index 2a3faa3..522a714 100644 --- a/src/services/clean-html.ts +++ b/src/services/clean-html.ts @@ -22,3 +22,27 @@ export function extractFirstSentence(text: string, maxLen = 200): string { export function stripHtmlTags(html: string): string { return stripHtml(html) } + +export function parseQuillList(html: string): string[] { + if (!html) return [] + const items: string[] = [] + const liRegex = /]*>([\s\S]*?)<\/li>/gi + let match + while ((match = liRegex.exec(html)) !== null) { + const text = match[1].replace(/<[^>]*>/g, '').trim() + if (text) items.push(text) + } + return items +} + +export function criteriaToJson(html: string): string { + return JSON.stringify(parseQuillList(html)) +} + +export function criteriaFromJson(json: string): string[] { + try { + return JSON.parse(json) + } catch { + return [] + } +} diff --git a/src/stores/workitems.ts b/src/stores/workitems.ts index 5b8ce52..66762b1 100644 --- a/src/stores/workitems.ts +++ b/src/stores/workitems.ts @@ -3,6 +3,7 @@ import { ref, computed } from 'vue' import { kappa } from '@/services/kappa-api' import { tauriDb, type UserStoryRecord, type EpicRecord } from '@/services/tauri-db' import { stripHtml } from '@/services/clean-html' +import { criteriaToJson, parseQuillList } from '@/services/clean-html' import { parseHierarchy, stripHierarchy, getItemType, type ItemType } from '@/services/hierarchy' import type { KappaUserStory, KappaLogbookEntry, KappaPlanningEntry, KappaEpicDevelopment } from '@/types/kappa' @@ -10,6 +11,7 @@ export interface EnrichedUserStory extends KappaUserStory { _itemType: ItemType _hierarchyPath: string | null _cleanTitle: string + _criteriaList: string[] } export interface EnrichedEpic extends KappaEpicDevelopment { @@ -55,15 +57,20 @@ export const useWorkItemsStore = defineStore('workitems', () => { } } - function enrichHU(hu: { title?: string; id?: number }, initiativeId: number): EnrichedUserStory { + function enrichHU(hu: { title?: string; id?: number; acceptance_criteria?: string | null; criterios_aceptacion?: string | null }, initiativeId: number): EnrichedUserStory { const h = parseHierarchy(hu.title || '') + const rawCriteria = hu.acceptance_criteria || hu.criterios_aceptacion || '' + const criteriaList = rawCriteria ? parseQuillList(rawCriteria) : [] return { id: hu.id ?? 0, title: hu.title || '', + acceptance_criteria: rawCriteria, + criterios_aceptacion: rawCriteria, initiative: initiativeId, _itemType: h?.items[h.items.length - 1]?.type || 'U', _hierarchyPath: h?.fullPath ?? null, _cleanTitle: h ? stripHierarchy(hu.title || '') : (hu.title || ''), + _criteriaList: criteriaList, } } @@ -166,7 +173,7 @@ export const useWorkItemsStore = defineStore('workitems', () => { code: safeStr(hu.code), title: String(hu.title || ''), description: stripHtml(String(hu.description || '')), - acceptance_criteria: safeStr(hu.acceptance_criteria), + acceptance_criteria: (hu.acceptance_criteria || hu.criterios_aceptacion || null) as string | null, status: safeStr(hu.status), priority: safeStr(hu.priority), story_points: null, diff --git a/src/types/kappa.ts b/src/types/kappa.ts index d43899f..ce4c128 100644 --- a/src/types/kappa.ts +++ b/src/types/kappa.ts @@ -42,6 +42,7 @@ export interface KappaUserStory { title: string description?: string acceptance_criteria?: string + criterios_aceptacion?: string status?: string priority?: string initiative: number | string diff --git a/src/views/DashboardView.vue b/src/views/DashboardView.vue index a53d963..ddb0f50 100644 --- a/src/views/DashboardView.vue +++ b/src/views/DashboardView.vue @@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n' import { useProjectsStore } from '@/stores/projects' import { useWorkItemsStore } from '@/stores/workitems' import { getTypeLabel, getTypeColor, getTypeIcon } from '@/services/hierarchy' -import { Activity, FileText, Layers, Clock } from 'lucide-vue-next' +import { Activity, FileText, Layers, Clock, Info } from 'lucide-vue-next' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' import { Skeleton } from '@/components/ui/skeleton' @@ -208,8 +208,20 @@ const statusLabel = (status: unknown) => { {{ getTypeLabel(hu._itemType) }} - - {{ hu._cleanTitle || hu.title }} + + {{ hu._cleanTitle || hu.title }} + + +
+

Criterios de aceptación

+
    +
  1. {{ c }}
  2. +
+
+