From 12d18322ffcc8a471221b790f85e191c0557832c Mon Sep 17 00:00:00 2001 From: borja Date: Mon, 8 Sep 2025 21:25:29 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20quitar=20cursivas=20de=20descripcio?= =?UTF-8?q?nes=20y=20a=C3=B1adir=20saltos=20entre=20grupos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: aider (openrouter/openai/gpt-5) --- src/services/command.ts | 38 ++++++++++++++++++++--------- tests/unit/services/command.test.ts | 9 ++++--- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/services/command.ts b/src/services/command.ts index 10c544c..7fb9471 100644 --- a/src/services/command.ts +++ b/src/services/command.ts @@ -239,7 +239,7 @@ export class CommandService { const rendered = items.map((t) => { const isOverdue = t.due_date ? t.due_date < todayYMD : false; const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : ''; - return `- ${codeId(t.id)} _${t.description || '(sin descripción)'}_${datePart} — ${ICONS.unassigned} sin responsable`; + return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${ICONS.unassigned} sin responsable`; }); const total = TaskService.countGroupUnassigned(context.groupId); @@ -288,9 +288,15 @@ export class CommandService { : `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`; const isOverdue = t.due_date ? t.due_date < todayYMD : false; const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : ''; - return `- ${codeId(t.id)} _${t.description || '(sin descripción)'}_${datePart} — ${owner}`; + return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${owner}`; })); sections.push(...rendered); + sections.push(''); + } + + // Quitar línea en blanco final si procede + if (sections.length > 0 && sections[sections.length - 1] === '') { + sections.pop(); } const totalMy = TaskService.countUserPending(context.sender); @@ -298,7 +304,7 @@ export class CommandService { sections.push(`… y ${totalMy - myItems.length} más`); } } else { - sections.push('No tienes tareas pendientes.'); + sections.push(italic('No tienes tareas pendientes.')); } // En contexto de grupo: mantener compatibilidad mostrando solo "sin responsable" del grupo actual @@ -309,11 +315,12 @@ export class CommandService { const groupName = GroupSyncService.activeGroupsCache.get(context.groupId) || context.groupId; const unassigned = TaskService.listGroupUnassigned(context.groupId, LIMIT); if (unassigned.length > 0) { + if (sections.length && sections[sections.length - 1] !== '') sections.push(''); sections.push(`${groupName} — Sin responsable`); const renderedUnassigned = unassigned.map((t) => { const isOverdue = t.due_date ? t.due_date < todayYMD : false; const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : ''; - return `- ${codeId(t.id)} _${t.description || '(sin descripción)'}_${datePart} — ${ICONS.unassigned} sin responsable`; + return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${ICONS.unassigned} sin responsable`; }); sections.push(...renderedUnassigned); @@ -337,11 +344,12 @@ export class CommandService { gid; if (unassigned.length > 0) { + if (sections.length && sections[sections.length - 1] !== '') sections.push(''); sections.push(`${groupName} — Sin responsable`); const renderedUnassigned = unassigned.map((t) => { const isOverdue = t.due_date ? t.due_date < todayYMD : false; const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : ''; - return `- ${codeId(t.id)} _${t.description || '(sin descripción)'}_${datePart} — ${ICONS.unassigned} sin responsable`; + return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${ICONS.unassigned} sin responsable`; }); sections.push(...renderedUnassigned); @@ -407,7 +415,7 @@ export class CommandService { : `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`; const isOverdue = t.due_date ? t.due_date < todayYMD : false; const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : ''; - return `- ${codeId(t.id)} _${t.description || '(sin descripción)'}_${datePart} — ${owner}`; + return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${owner}`; })); const total = TaskService.countGroupPending(context.groupId); @@ -426,7 +434,7 @@ export class CommandService { if (items.length === 0) { return [{ recipient: context.sender, - message: 'No tienes tareas pendientes.' + message: italic('No tienes tareas pendientes.') }]; } @@ -458,9 +466,15 @@ export class CommandService { : `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`; const isOverdue = t.due_date ? t.due_date < todayYMD : false; const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : ''; - return `- ${codeId(t.id)} _${t.description || '(sin descripción)'}_${datePart} — ${owner}`; + return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${owner}`; })); sections.push(...rendered); + sections.push(''); + } + + // Quitar línea en blanco final si procede + if (sections.length > 0 && sections[sections.length - 1] === '') { + sections.pop(); } if (total > items.length) { @@ -511,14 +525,14 @@ export class CommandService { const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : ''; return [{ recipient: context.sender, - message: `ℹ️ ${codeId(id)} ya estaba completada — _${res.task?.description || '(sin descripción)'}_${due}` + message: `ℹ️ ${codeId(id)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}` }]; } const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : ''; return [{ recipient: context.sender, - message: `${ICONS.complete} ${codeId(id)} completada — _${res.task?.description || '(sin descripción)'}_${due}` + message: `${ICONS.complete} ${codeId(id)} completada — ${res.task?.description || '(sin descripción)'}${due}` }]; } @@ -571,7 +585,7 @@ export class CommandService { } const lines = [ - `${ICONS.take} Has tomado ${codeId(id)}`, + italic(`${ICONS.take} Has tomado ${codeId(id)}`), `${res.task?.description || '(sin descripción)'}`, res.task?.due_date ? `${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '' ].filter(Boolean); @@ -789,7 +803,7 @@ export class CommandService { ? `${ICONS.unassigned} sin responsable${groupName ? ` (${groupName})` : ''}` : `${assignmentUserIds.length > 1 ? '👥' : '👤'} ${assignedDisplayNames.join(', ')}`; const ackLines = [ - `${ICONS.create} ${codeId(taskId)} _${description || '(sin descripción)'}_`, + `${ICONS.create} ${codeId(taskId)} ${description || '(sin descripción)'}`, dueFmt ? `${ICONS.date} ${dueFmt}` : null, ownerPart ].filter(Boolean); diff --git a/tests/unit/services/command.test.ts b/tests/unit/services/command.test.ts index fac0895..5ddb92d 100644 --- a/tests/unit/services/command.test.ts +++ b/tests/unit/services/command.test.ts @@ -93,8 +93,8 @@ test('listar “mis” por defecto en DM con /t ver', async () => { const msg = responses[0].message; expect(msg).toContain('Test Group'); expect(msg).toContain('Group 2'); - expect(msg).toMatch(/- `\d{4}` _G1 Task_/); - expect(msg).toMatch(/- `\d{4}` _G2 Task_/); + expect(msg).toMatch(/- `\d{4}` G1 Task/); + expect(msg).toMatch(/- `\d{4}` G2 Task/); }); test('completar tarea: camino feliz, ya completada y no encontrada', async () => { @@ -311,8 +311,9 @@ describe('CommandService', () => { expect(responses[0].recipient).toBe('1234567890'); // Debe empezar con "📝 `0001` " expect(responses[0].message).toMatch(/^📝 `\d{4}` /); - // Debe contener la descripción en cursiva compacta - expect(responses[0].message).toContain('_Test task_'); + // Debe mostrar la descripción en texto plano (sin cursiva) + expect(responses[0].message).toContain(' Test task'); + expect(responses[0].message).not.toContain('_Test task_'); // No debe usar el texto antiguo "Tarea creada" expect(responses[0].message).not.toMatch(/Tarea \d+ creada/); });