fix(rgi): remove wrong dueDate lock — always show download button

The dueDate-based lock was incorrect: some documents with future
dueDate ARE downloadable. The availability depends on eTerra internal
rules, not predictably on dueDate.

Now all documents show a download button. If server-side download
fails (fileVisibility 404), it redirects to eTerra direct URL
which works in the user's browser session.

Filters changed to: Solutionate / Confirmate / Toate

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
AI Assistant
2026-03-24 23:23:48 +02:00
parent a191a684b2
commit c1006f395c
+11 -35
View File
@@ -260,22 +260,12 @@ function IssuedDocsPanel({
); );
} }
const isLocked = dueDate > Date.now();
return ( return (
<div className="space-y-1.5 py-2"> <div className="space-y-1.5 py-2">
<div className="flex items-center gap-2 mb-2"> <p className="text-xs font-medium text-muted-foreground mb-2">
<p className="text-xs font-medium text-muted-foreground">
{docs.length} document{docs.length > 1 ? "e" : ""} eliberat {docs.length} document{docs.length > 1 ? "e" : ""} eliberat
{docs.length > 1 ? "e" : ""} {docs.length > 1 ? "e" : ""}:
</p> </p>
{isLocked && (
<Badge variant="outline" className="text-[10px] border-amber-300 text-amber-600 dark:text-amber-400">
<Clock className="h-3 w-3 mr-0.5" />
Disponibile de la {fmtTs(dueDate)}
</Badge>
)}
</div>
{docs.map((doc, i) => ( {docs.map((doc, i) => (
<div <div
key={doc.documentPk || i} key={doc.documentPk || i}
@@ -306,14 +296,7 @@ function IssuedDocsPanel({
</div> </div>
</div> </div>
</div> </div>
<div className="flex items-center gap-1 shrink-0"> <Button size="sm" variant="outline" className="gap-1 shrink-0" asChild>
{isLocked ? (
<Badge variant="secondary" className="text-[10px] text-muted-foreground">
<Clock className="h-3 w-3 mr-0.5" />
{fmtTs(dueDate)}
</Badge>
) : (
<Button size="sm" variant="outline" className="gap-1" asChild>
<a <a
href={`/api/eterra/rgi/download-doc?workspaceId=${doc.workspaceId || workspaceId}&applicationId=${doc.applicationId || applicationPk}&documentPk=${doc.documentPk}&documentTypeId=${doc.documentTypeId}`} href={`/api/eterra/rgi/download-doc?workspaceId=${doc.workspaceId || workspaceId}&applicationId=${doc.applicationId || applicationPk}&documentPk=${doc.documentPk}&documentTypeId=${doc.documentTypeId}`}
target="_blank" target="_blank"
@@ -323,8 +306,6 @@ function IssuedDocsPanel({
Descarca Descarca
</a> </a>
</Button> </Button>
)}
</div>
</div> </div>
))} ))}
</div> </div>
@@ -403,16 +384,14 @@ export default function RgiTestPage() {
setLoading(false); setLoading(false);
}, [workspaceId, orgUnitId, year]); }, [workspaceId, orgUnitId, year]);
const [filterMode, setFilterMode] = useState<"all" | "ready" | "pending">("ready"); const [filterMode, setFilterMode] = useState<"all" | "solved" | "confirmed">("solved");
// Client-side filter // Client-side filter
const filtered = useMemo(() => { const filtered = useMemo(() => {
if (filterMode === "all") return applications; if (filterMode === "all") return applications;
const now = Date.now();
return applications.filter((a) => { return applications.filter((a) => {
if (a.hasSolution !== 1) return false; if (filterMode === "solved") return a.hasSolution === 1;
if (filterMode === "ready") return a.dueDate <= now; // termen trecut = descarcabil if (filterMode === "confirmed") return a.stateCode === "CONFIRMED";
if (filterMode === "pending") return a.dueDate > now; // termen viitor = blocat
return true; return true;
}); });
}, [applications, filterMode]); }, [applications, filterMode]);
@@ -498,8 +477,8 @@ export default function RgiTestPage() {
<div className="flex items-center gap-3 pt-2 border-t flex-wrap"> <div className="flex items-center gap-3 pt-2 border-t flex-wrap">
<div className="flex gap-1 p-0.5 bg-muted rounded-md"> <div className="flex gap-1 p-0.5 bg-muted rounded-md">
{([ {([
{ id: "ready" as const, label: "Descarcabile acum", desc: "solutionate + termen trecut" }, { id: "solved" as const, label: "Solutionate", desc: "lucrari cu solutie" },
{ id: "pending" as const, label: "In asteptare", desc: "solutionate + termen viitor (blocate)" }, { id: "confirmed" as const, label: "Confirmate", desc: "solutie confirmata" },
{ id: "all" as const, label: "Toate", desc: "" }, { id: "all" as const, label: "Toate", desc: "" },
]).map((opt) => ( ]).map((opt) => (
<button <button
@@ -572,7 +551,6 @@ export default function RgiTestPage() {
const pk = app.applicationPk; const pk = app.applicationPk;
const isExpanded = expandedPk === pk; const isExpanded = expandedPk === pk;
const solved = app.hasSolution === 1; const solved = app.hasSolution === 1;
const downloadable = solved && app.dueDate <= Date.now();
return ( return (
<React.Fragment key={pk}> <React.Fragment key={pk}>
@@ -585,11 +563,9 @@ export default function RgiTestPage() {
setExpandedPk(isExpanded ? null : pk) setExpandedPk(isExpanded ? null : pk)
} }
> >
<td className="px-2 py-2.5 w-8" title={downloadable ? "Descarcabil" : solved ? `Blocat pana la ${fmtTs(app.dueDate)}` : "In lucru"}> <td className="px-2 py-2.5 w-8" title={solved ? "Solutionata" : "In lucru"}>
{downloadable ? ( {solved ? (
<Download className="h-4 w-4 text-emerald-500" /> <CheckCircle2 className="h-4 w-4 text-emerald-500" />
) : solved ? (
<Clock className="h-4 w-4 text-amber-500" />
) : ( ) : (
<Clock className="h-4 w-4 text-muted-foreground" /> <Clock className="h-4 w-4 text-muted-foreground" />
)} )}