feat: Sprint 2 — data storytelling and visual richness
Timeline project color system: - 16-color deterministic palette (same project = same color always) - Resource panel: allocation blocks colored by project instead of uniform green - Project panel: colored left border + dot on project headers - ProjectColorLegend: floating strip showing color-to-project mapping - Utilization intensity tint: subtle background gradient on resource rows Table visual enhancements: - Resources: inline 3px utilization bar below chargeability percentage - Resources: 32px avatar circles with initials + role-derived colors - Projects: animated budget bars, styled resource count badges - Allocations: 3px left border colored by status (green/amber/blue/gray/red) KPI progress rings: - Budget utilization: ProgressRing wrapping AnimatedNumber on dashboard - Chargeability report: ring on average chargeability summary card - Resource detail: rings on chargeability target + actual metrics - Vacation balance: ring showing remaining days with color thresholds - Demand widget: mini rings on FTE fill rate per project - Resource detail: FadeIn on SkillRadarChart Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import React, { useState, useMemo, useCallback } from "react";
|
||||
import { trpc } from "~/lib/trpc/client.js";
|
||||
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
|
||||
import { ProgressRing } from "~/components/ui/ProgressRing.js";
|
||||
|
||||
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -445,7 +446,16 @@ export function ChargeabilityReportClient() {
|
||||
</div>
|
||||
<div className="app-surface p-4">
|
||||
<div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-gray-500 inline-flex items-center gap-0.5">Average Chargeability<InfoTooltip content="FTE-weighted average chargeability across all visible resources. Formula: sum(FTE x Chg%) / sum(FTE)." /></div>
|
||||
<div className={`mt-2 text-3xl font-semibold ${chgColor(averageChargeability, averageTarget)}`}>{pct(averageChargeability)}</div>
|
||||
<div className="mt-2 flex items-center gap-3">
|
||||
<ProgressRing
|
||||
value={Math.round(averageChargeability * 100)}
|
||||
size={56}
|
||||
strokeWidth={4}
|
||||
color={averageChargeability >= averageTarget ? "var(--color-green-500, #22c55e)" : averageChargeability >= averageTarget - 0.1 ? "var(--color-amber-500, #f59e0b)" : "var(--color-red-500, #ef4444)"}
|
||||
>
|
||||
<span className={`text-lg font-semibold ${chgColor(averageChargeability, averageTarget)}`}>{pct(averageChargeability)}</span>
|
||||
</ProgressRing>
|
||||
</div>
|
||||
<div className="mt-1 text-sm text-gray-500">Weighted across visible resources</div>
|
||||
</div>
|
||||
<div className="app-surface p-4">
|
||||
|
||||
Reference in New Issue
Block a user