fix: differentiate Conex (linkedEntryIds) vs Inchide (threadParentId) semantics

- Conex button now adds to linkedEntryIds (for clarificari/solicitari)
  instead of setting threadParentId
- Inchide button sets threadParentId (direct reply) + auto-closes parent
- Fix Sterge button persistence bug: threadParentId now saves as empty
  string instead of undefined (which was stripped in JSON serialization)
- Card headers: "Conex cu X" (amber) vs "Raspuns la X" (blue + green)
- Add conexTo prop to RegistryEntryForm for linked entry pre-fill

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
AI Assistant
2026-03-10 21:29:56 +02:00
parent 85077251f3
commit 4ac4a48cad
3 changed files with 33 additions and 15 deletions
@@ -70,9 +70,11 @@ export function RegistraturaModule() {
const [viewMode, setViewMode] = useState<ViewMode>("list"); const [viewMode, setViewMode] = useState<ViewMode>("list");
const [editingEntry, setEditingEntry] = useState<RegistryEntry | null>(null); const [editingEntry, setEditingEntry] = useState<RegistryEntry | null>(null);
const [viewingEntry, setViewingEntry] = useState<RegistryEntry | null>(null); const [viewingEntry, setViewingEntry] = useState<RegistryEntry | null>(null);
/** Entry to reply to (conex) — pre-sets threadParentId in new form */ /** Entry to reply to (Inchide flow) — pre-sets threadParentId + flips direction */
const [replyToEntry, setReplyToEntry] = useState<RegistryEntry | null>(null); const [replyToEntry, setReplyToEntry] = useState<RegistryEntry | null>(null);
/** If set, the parent entry will be closed after saving the new conex entry */ /** Entry to link as conex (Conex flow) — adds to linkedEntryIds, keeps direction */
const [conexToEntry, setConexToEntry] = useState<RegistryEntry | null>(null);
/** If set, the parent entry will be closed after saving the new reply entry */
const [closesEntryId, setClosesEntryId] = useState<string | null>(null); const [closesEntryId, setClosesEntryId] = useState<string | null>(null);
const [closingId, setClosingId] = useState<string | null>(null); const [closingId, setClosingId] = useState<string | null>(null);
const [linkCheckId, setLinkCheckId] = useState<string | null>(null); const [linkCheckId, setLinkCheckId] = useState<string | null>(null);
@@ -160,6 +162,7 @@ export function RegistraturaModule() {
setClosesEntryId(null); setClosesEntryId(null);
} }
setReplyToEntry(null); setReplyToEntry(null);
setConexToEntry(null);
setViewMode("list"); setViewMode("list");
}; };
@@ -176,17 +179,20 @@ export function RegistraturaModule() {
setViewingEntry(full ?? entry); setViewingEntry(full ?? entry);
}; };
const handleReply = (entry: RegistryEntry) => { /** Conex: create a new entry linked to this one (clarificari, solicitari) */
setReplyToEntry(entry); const handleConex = (entry: RegistryEntry) => {
setConexToEntry(entry);
setReplyToEntry(null);
setClosesEntryId(null); setClosesEntryId(null);
setViewingEntry(null); setViewingEntry(null);
setEditingEntry(null); setEditingEntry(null);
setViewMode("add"); setViewMode("add");
}; };
/** Close entry via conex: create reply entry that closes the parent */ /** Inchide: create a reply entry (raspuns la) that closes the parent */
const handleCloseViaConex = (entry: RegistryEntry) => { const handleCloseViaReply = (entry: RegistryEntry) => {
setReplyToEntry(entry); setReplyToEntry(entry);
setConexToEntry(null);
setClosesEntryId(entry.id); setClosesEntryId(entry.id);
setViewingEntry(null); setViewingEntry(null);
setEditingEntry(null); setEditingEntry(null);
@@ -248,6 +254,7 @@ export function RegistraturaModule() {
setViewMode("list"); setViewMode("list");
setEditingEntry(null); setEditingEntry(null);
setReplyToEntry(null); setReplyToEntry(null);
setConexToEntry(null);
setClosesEntryId(null); setClosesEntryId(null);
}; };
@@ -426,8 +433,8 @@ export function RegistraturaModule() {
onView={handleView} onView={handleView}
onEdit={handleEdit} onEdit={handleEdit}
onDelete={handleDelete} onDelete={handleDelete}
onClose={handleCloseViaConex} onClose={handleCloseViaReply}
onReply={handleReply} onReply={handleConex}
/> />
{!loading && ( {!loading && (
@@ -444,7 +451,7 @@ export function RegistraturaModule() {
<CardTitle className="flex items-center gap-2"> <CardTitle className="flex items-center gap-2">
{replyToEntry ? ( {replyToEntry ? (
<> <>
Conex la {replyToEntry.number} Raspuns la {replyToEntry.number}
<Badge variant="outline" className="text-xs text-blue-600 border-blue-300"> <Badge variant="outline" className="text-xs text-blue-600 border-blue-300">
Raspuns Raspuns
</Badge> </Badge>
@@ -454,6 +461,13 @@ export function RegistraturaModule() {
</Badge> </Badge>
)} )}
</> </>
) : conexToEntry ? (
<>
Conex cu {conexToEntry.number}
<Badge variant="outline" className="text-xs text-amber-600 border-amber-300">
Clarificare
</Badge>
</>
) : ( ) : (
<> <>
Inregistrare noua Inregistrare noua
@@ -468,6 +482,7 @@ export function RegistraturaModule() {
<RegistryEntryForm <RegistryEntryForm
allEntries={allEntries} allEntries={allEntries}
replyTo={replyToEntry ?? undefined} replyTo={replyToEntry ?? undefined}
conexTo={conexToEntry ?? undefined}
onSubmit={handleAdd} onSubmit={handleAdd}
onCancel={handleCancel} onCancel={handleCancel}
onCreateContact={handleCreateContact} onCreateContact={handleCreateContact}
@@ -504,9 +519,9 @@ export function RegistraturaModule() {
if (!open) setViewingEntry(null); if (!open) setViewingEntry(null);
}} }}
onEdit={handleEdit} onEdit={handleEdit}
onClose={handleCloseViaConex} onClose={handleCloseViaReply}
onDelete={handleDelete} onDelete={handleDelete}
onReply={handleReply} onReply={handleConex}
allEntries={allEntries} allEntries={allEntries}
/> />
@@ -87,8 +87,10 @@ import { getDeadlineType } from "../services/deadline-catalog";
interface RegistryEntryFormProps { interface RegistryEntryFormProps {
initial?: RegistryEntry; initial?: RegistryEntry;
/** Pre-fill as reply (conex) to this entry — sets threadParentId, flips direction */ /** Pre-fill as reply to this entry — sets threadParentId, flips direction (used by "Inchide") */
replyTo?: RegistryEntry; replyTo?: RegistryEntry;
/** Pre-fill as related/conex entry — adds to linkedEntryIds, keeps direction (used by "Conex") */
conexTo?: RegistryEntry;
allEntries?: RegistryEntry[]; allEntries?: RegistryEntry[];
onSubmit: ( onSubmit: (
data: Omit<RegistryEntry, "id" | "number" | "createdAt" | "updatedAt">, data: Omit<RegistryEntry, "id" | "number" | "createdAt" | "updatedAt">,
@@ -109,6 +111,7 @@ interface RegistryEntryFormProps {
export function RegistryEntryForm({ export function RegistryEntryForm({
initial, initial,
replyTo, replyTo,
conexTo,
allEntries, allEntries,
onSubmit, onSubmit,
onCancel, onCancel,
@@ -193,7 +196,7 @@ export function RegistryEntryForm({
); );
const [notes, setNotes] = useState(initial?.notes ?? ""); const [notes, setNotes] = useState(initial?.notes ?? "");
const [linkedEntryIds, setLinkedEntryIds] = useState<string[]>( const [linkedEntryIds, setLinkedEntryIds] = useState<string[]>(
initial?.linkedEntryIds ?? [], initial?.linkedEntryIds ?? (conexTo ? [conexTo.id] : []),
); );
const [attachments, setAttachments] = useState<RegistryAttachment[]>( const [attachments, setAttachments] = useState<RegistryAttachment[]>(
initial?.attachments ?? [], initial?.attachments ?? [],
@@ -557,7 +560,7 @@ export function RegistryEntryForm({
deadline: deadline || undefined, deadline: deadline || undefined,
assignee: assignee || undefined, assignee: assignee || undefined,
assigneeContactId: assigneeContactId || undefined, assigneeContactId: assigneeContactId || undefined,
threadParentId: threadParentId || undefined, threadParentId: threadParentId || "",
recipientRegNumber: recipientRegNumber || undefined, recipientRegNumber: recipientRegNumber || undefined,
recipientRegDate: recipientRegDate || undefined, recipientRegDate: recipientRegDate || undefined,
expiryDate: expiryDate || undefined, expiryDate: expiryDate || undefined,
@@ -483,7 +483,7 @@ export function RegistryTable({
e.stopPropagation(); e.stopPropagation();
onReply(entry); onReply(entry);
}} }}
title="Conex — creeaza raspuns" title="Conex — clarificare / solicitare"
> >
<Reply className="h-3.5 w-3.5" /> <Reply className="h-3.5 w-3.5" />
</Button> </Button>