fix: version 2.11.1 -- mueve los contadores de 2.11.0 de columnas de grilla a badges de pestaña

La 2.11.0 agrego los contadores de dependencias/comentarios/documentos/miembros como columnas
nuevas en las tablas de Proyectos y Actividades -- no era el pedido original, desbordaba la
grilla. Se revierten esas columnas (y el componente CountBadge que solo ellas usaban) y los
contadores van donde correspondia desde el principio: como badge junto al nombre de cada
pestaña, al mismo estilo que ya usaba "Tareas n/n" (componente Tabs + .tab-badge):
- Proyecto: pestañas Miembros, Actividades (completas/total), Comentarios, Documentos.
- Actividad: pestaña Dependencias (ya existia Tareas/Comentarios/Documentos, solo faltaba esta).

De paso: Tabs.jsx ocultaba el badge cuando count era 0 (!!tab.count) -- se cambia a mostrar
siempre que la pestaña mande la prop (count !== undefined), para que 0 se vea como "0" y no
desaparezca. CommentsPanel/AttachmentsPanel ganan un onChanged opcional para que el contador
de Comentarios/Documentos del PROYECTO se actualice al tiro sin tener que recargar la pagina
(el de la actividad ya se refrescaba solo al cambiar de pestaña).

El backend de 2.11.0 (subconsultas dependencies_count/comments_count/documents_count/
members_count/activities_total/activities_complete en los LIST_SELECT) se mantiene igual,
solo cambia donde el frontend los usa.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-10-14 11:53:43 -05:00
parent 4520abe96f
commit d44f96bb6c
13 changed files with 29 additions and 40 deletions
+3 -2
View File
@@ -13,7 +13,7 @@ import hljsDark from 'highlight.js/styles/vs2015.css?inline';
const VIEWABLE_MIME = new Set(['text/plain', 'text/markdown']);
export function AttachmentsPanel({ entityType, entityId }) {
export function AttachmentsPanel({ entityType, entityId, onChanged }) {
const { t, openDialog, theme } = useUi();
const runAction = useAction();
const { data: files, reload } = useAsync(() => listAttachments(entityType, entityId), [entityType, entityId]);
@@ -41,6 +41,7 @@ export function AttachmentsPanel({ entityType, entityId }) {
await runAction(async () => {
await uploadAttachment(entityType, entityId, file);
await reload();
onChanged?.(); // refresca el contador de la pestaña "Documentos" en el padre
});
e.target.value = '';
}
@@ -52,7 +53,7 @@ export function AttachmentsPanel({ entityType, entityId }) {
message: t('common_confirm_delete_msg'),
actions: [
{ label: t('common_cancel'), variant: 'standard' },
{ label: t('common_delete'), variant: 'danger', onClick: () => runAction(async () => { await deleteAttachment(file.id); await reload(); }) },
{ label: t('common_delete'), variant: 'danger', onClick: () => runAction(async () => { await deleteAttachment(file.id); await reload(); onChanged?.(); }) },
],
});
}
+2 -1
View File
@@ -5,7 +5,7 @@ import { useAsync, useAction } from '../hooks/useAsync.js';
import { listComments, createComment } from '../services/comments.js';
import { Button } from './Button.jsx';
export function CommentsPanel({ entityType, entityId }) {
export function CommentsPanel({ entityType, entityId, onChanged }) {
const { t } = useUi();
const runAction = useAction();
const { data: comments, reload } = useAsync(() => listComments(entityType, entityId), [entityType, entityId]);
@@ -17,6 +17,7 @@ export function CommentsPanel({ entityType, entityId }) {
await createComment(entityType, entityId, message.trim());
setMessage('');
await reload();
onChanged?.(); // refresca el contador de la pestaña "Comentarios" en el padre
});
}
-11
View File
@@ -1,11 +0,0 @@
// Contador chico con icono para columnas de listado (dependencias/comentarios/documentos/
// miembros). Siempre muestra el numero, incluido 0 -- a diferencia de SharedWithIcon/Tabs que
// ocultan el badge en 0, aca el pedido es que el contador siempre sea visible.
export function CountBadge({ icon: Icon, count, title }) {
return (
<span className="count-badge" title={title}>
<Icon size={14} />
{count}
</span>
);
}
+3 -1
View File
@@ -4,7 +4,9 @@ export function Tabs({ tabs, active, onChange }) {
{tabs.map((tab) => (
<button key={tab.key} className={`tab-item ${active === tab.key ? 'active' : ''}`} onClick={() => onChange(tab.key)}>
{tab.label}
{!!tab.count && <span className="tab-badge">{tab.count}</span>}
{/* count=0 SI se muestra (badge "0") -- solo se omite si la pestaña ni siquiera manda
la prop (undefined), para pestañas que no tienen numero que mostrar (Info/Gantt). */}
{tab.count !== undefined && <span className="tab-badge">{tab.count}</span>}
</button>
))}
</div>