fix(allocations): recover from fully filtered empty state

This commit is contained in:
2026-04-01 15:16:57 +02:00
parent 7df751d5eb
commit fd75628e9d
3 changed files with 185 additions and 2 deletions
@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect, useMemo, useCallback } from "react";
import { useState, useEffect, useMemo, useCallback, useRef } from "react";
import { formatDate } from "~/lib/format.js";
import { trpc } from "~/lib/trpc/client.js";
import { AllocationModal } from "./AllocationModal.js";
@@ -29,6 +29,7 @@ import {
toggleCollapsedAllocationGroup,
type CollapsedAllocationGroups,
} from "./allocationGroupState.js";
import { getAllocationEmptyState, shouldAutoRelaxAllocationFilters } from "./allocationVisibilityState.js";
/** Left-border color by allocation status for instant visual scanning */
const STATUS_LEFT_BORDER: Record<string, string> = {
@@ -202,6 +203,7 @@ export function AllocationsClient() {
);
// Track expanded project sub-groups: key = "resourceId::projectId"
const [expandedSubGroups, setExpandedSubGroups] = useState<Set<string>>(new Set());
const hasEvaluatedInitialVisibility = useRef(false);
const toggleViewMode = useCallback(() => {
setViewMode((prev) => {
@@ -351,6 +353,49 @@ export function AllocationsClient() {
...(hideDraftProjects ? [{ label: "Hiding draft projects", onRemove: () => setHideDraftProjects(false) }] : []),
];
const emptyState = getAllocationEmptyState({
totalAssignments: assignmentList.length,
totalDemands: demandList.length,
visibleAssignments: filteredAllocations.length,
visibleDemands: filteredDemands.length,
hidePastProjects,
hideCompletedProjects,
hideDraftProjects,
});
useEffect(() => {
if (isLoading || hasEvaluatedInitialVisibility.current) {
return;
}
hasEvaluatedInitialVisibility.current = true;
if (
shouldAutoRelaxAllocationFilters({
totalAssignments: assignmentList.length,
totalDemands: demandList.length,
visibleAssignments: filteredAllocations.length,
visibleDemands: filteredDemands.length,
hidePastProjects,
hideCompletedProjects,
hideDraftProjects,
})
) {
setHidePastProjects(false);
setHideCompletedProjects(false);
setHideDraftProjects(false);
}
}, [
assignmentList.length,
demandList.length,
filteredAllocations.length,
filteredDemands.length,
hideCompletedProjects,
hideDraftProjects,
hidePastProjects,
isLoading,
]);
function formatPeriod(alloc: AllocationWithDetails) {
return formatDate(alloc.startDate) + " \u2192 " + formatDate(alloc.endDate);
}
@@ -633,7 +678,21 @@ export function AllocationsClient() {
{!isLoading && sorted.length === 0 && (
<tr>
<td colSpan={totalColSpan} className="py-12 text-center text-sm text-gray-500 dark:text-gray-400">No assignments found.</td>
<td colSpan={totalColSpan} className="py-12 text-center text-sm text-gray-500 dark:text-gray-400">
<div className="flex flex-col items-center gap-2">
<p className="font-medium text-gray-700 dark:text-gray-200">{emptyState.title}</p>
<p>{emptyState.detail}</p>
{emptyState.showResetAction && (
<button
type="button"
onClick={clearAll}
className="rounded-lg border border-gray-300 px-3 py-1.5 text-xs font-medium text-gray-700 transition hover:border-gray-400 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-200 dark:hover:bg-gray-800"
>
Show all assignments
</button>
)}
</div>
</td>
</tr>
)}