feat: version 2.17.8 -- Panel: medidor y detalle en "Actividades pendientes"
Base = actividades no eliminadas de proyectos no cancelados; el conteo de pendientes pasa a usar el mismo criterio (antes incluia eliminadas). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,33 @@ function ProjectsDetail({ title, projects, getDueStatus, onBack }) {
|
||||
);
|
||||
}
|
||||
|
||||
// Igual que ProjectsDetail pero para actividades (clic abre el proyecto en la actividad).
|
||||
function ActivitiesDetail({ title, activities, onBack }) {
|
||||
const { t } = useUi();
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<div className="panel-card">
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
|
||||
<h3>{title}</h3>
|
||||
<button type="button" className="link-button" onClick={onBack}>{t('dashboard_back_to_my_activities')}</button>
|
||||
</div>
|
||||
{activities.length === 0 && <div className="text-muted">{t('common_empty')}</div>}
|
||||
{activities.map((a) => (
|
||||
<div key={a.id} onClick={() => navigate(`/proyectos/${a.project_id}?tab=activities&activity=${a.id}`)} style={ROW_STYLE}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ fontSize: '.82rem', fontWeight: 600 }}>{a.code} — {a.name}</div>
|
||||
<div className="text-muted" style={{ fontSize: '.72rem' }}>
|
||||
{a.project_code} — {a.project_name} · {a.responsible_name || '—'} · {a.due_date ? String(a.due_date).slice(0, 10) : '—'}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ width: 120 }}><ProgressBar value={Number(a.progress_pct)} /></div>
|
||||
<DueBadge status={a.dueStatus} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function DashboardPage() {
|
||||
const { t } = useUi();
|
||||
const navigate = useNavigate();
|
||||
@@ -49,7 +76,9 @@ export default function DashboardPage() {
|
||||
const toggleDetail = (key) => setDetail((d) => (d === key ? null : key));
|
||||
|
||||
if (!data) return <div className="text-muted">{t('common_loading')}</div>;
|
||||
const { kpis, myActivities, projectsByStatus, overdueProjects, activeProjects } = data;
|
||||
const { kpis, myActivities, projectsByStatus, overdueProjects, activeProjects, pendingActivities } = data;
|
||||
const activitiesTotal = Number(kpis.nonCancelledActivities) || 0;
|
||||
const pending = ratioOf(kpis.pendingActivities, activitiesTotal);
|
||||
const activeTotal = Number(kpis.activeProjects) || 0;
|
||||
const nonCancelledTotal = Number(kpis.nonCancelledProjects) || 0;
|
||||
const active = ratioOf(kpis.activeProjects, nonCancelledTotal);
|
||||
@@ -75,7 +104,13 @@ export default function DashboardPage() {
|
||||
selected={detail === 'overdue'}
|
||||
/>
|
||||
<KpiCard label={t('dashboard_due_soon_projects')} value={kpis.dueSoonProjects} />
|
||||
<KpiCard label={t('dashboard_pending_activities')} value={kpis.pendingActivities} />
|
||||
<KpiCard
|
||||
label={t('dashboard_pending_activities')}
|
||||
value={`${pending.pct}%`}
|
||||
gauge={{ ratio: pending.ratio, color: 'warning', caption: `${kpis.pendingActivities} ${t('common_of')} ${activitiesTotal}` }}
|
||||
onClick={() => toggleDetail('pending')}
|
||||
selected={detail === 'pending'}
|
||||
/>
|
||||
<KpiCard label={t('dashboard_overdue_activities')} value={kpis.overdueActivities} />
|
||||
<KpiCard label={t('dashboard_today_activities')} value={kpis.todayActivities} />
|
||||
<KpiCard label={t('dashboard_average_progress')} value={`${kpis.averageProgress}%`} />
|
||||
@@ -87,6 +122,9 @@ export default function DashboardPage() {
|
||||
{detail === 'active' && (
|
||||
<ProjectsDetail title={t('dashboard_my_active_projects')} projects={activeProjects} getDueStatus={(p) => p.dueStatus} onBack={() => setDetail(null)} />
|
||||
)}
|
||||
{detail === 'pending' && (
|
||||
<ActivitiesDetail title={t('dashboard_pending_activities_list')} activities={pendingActivities} onBack={() => setDetail(null)} />
|
||||
)}
|
||||
{!detail && (
|
||||
<div className="panel-card">
|
||||
<h3>{t('dashboard_my_activities')}</h3>
|
||||
|
||||
Reference in New Issue
Block a user