+ );
+}
+
function MarketHeader({
title,
hint,
diff --git a/apps/jarvis-web/src/components/Projects/ProjectBoard.tsx b/apps/jarvis-web/src/components/Projects/ProjectBoard.tsx
index 733a24a..c715cc0 100644
--- a/apps/jarvis-web/src/components/Projects/ProjectBoard.tsx
+++ b/apps/jarvis-web/src/components/Projects/ProjectBoard.tsx
@@ -170,21 +170,28 @@ export function ProjectBoard({
return { boardRequirements: board, triageRequirements: triage };
}, [filteredRequirements]);
- const grouped = useMemo(() => {
+ const { grouped, orphans } = useMemo(() => {
// Seed with the active column ids so empty lanes still render.
// Requirements whose `status` doesn't match any current column id
- // (e.g. a column was just removed) land in a synthetic bucket
- // keyed by the orphan status — they're not displayed on the
- // board, but the data isn't lost on disk and a future column
- // edit can restore them.
+ // (e.g. a column was just removed) collect into a separate
+ // bucket and surface as a warning above the board so the data
+ // doesn't silently vanish when columns are edited.
const map: Record = {};
for (const c of cols) map[c.id] = [];
+ const orphans: Requirement[] = [];
for (const r of boardRequirements) {
if (map[r.status]) map[r.status].push(r);
+ else orphans.push(r);
}
- return map;
+ return { grouped: map, orphans };
}, [boardRequirements, cols]);
+ const orphanStatuses = useMemo(() => {
+ const set = new Set();
+ for (const r of orphans) set.add(r.status);
+ return Array.from(set);
+ }, [orphans]);
+
return (
+ )}
+
{/* Tailwind utility on the kanban frame: ensures the columns row
can shrink against the sidebar without forcing a horizontal
scrollbar from the legacy `min-width: 0` plumbing. The
@@ -804,14 +830,6 @@ function RequirementCard({
{sessions}×
)}
- {requirement.acceptance_policy === "human" && (
-
- {t("reqAcceptancePolicyHumanBadge")}
-
- )}
{t("reqClickHint")}