Fix invitation import reactivity and focus imported invitation

This commit is contained in:
2026-04-27 12:46:52 +00:00
parent 53ad7b729e
commit b708c8c1f8
3 changed files with 30 additions and 5 deletions

View File

@@ -102,6 +102,7 @@ export function InvitationScreen(): React.ReactElement {
// Two phases: first the ID input dialog, then the multi-step import flow. // Two phases: first the ID input dialog, then the multi-step import flow.
const [showIdDialog, setShowIdDialog] = useState(false); const [showIdDialog, setShowIdDialog] = useState(false);
const [importingId, setImportingId] = useState<string | null>(null); const [importingId, setImportingId] = useState<string | null>(null);
const [pendingImportedInvitationId, setPendingImportedInvitationId] = useState<string | null>(null);
// ── Template cache ─────────────────────────────────────────────────────── // ── Template cache ───────────────────────────────────────────────────────
const [templateCache, setTemplateCache] = useState<Map<string, XOTemplate>>(new Map()); const [templateCache, setTemplateCache] = useState<Map<string, XOTemplate>>(new Map());
@@ -161,7 +162,7 @@ export function InvitationScreen(): React.ReactElement {
}); });
return [importItem, ...invitationItems]; return [importItem, ...invitationItems];
}, [invitations, templateCache]); }, [invitations.length, templateCache]);
const selectedItem = listItems[selectedIndex]; const selectedItem = listItems[selectedIndex];
const selectedInvitation = selectedItem?.value ?? null; const selectedInvitation = selectedItem?.value ?? null;
@@ -196,10 +197,30 @@ export function InvitationScreen(): React.ReactElement {
/** /**
* Import flow closed (completed or cancelled). * Import flow closed (completed or cancelled).
*/ */
const handleImportFlowClose = useCallback(() => { const handleImportFlowClose = useCallback((importedInvitationId?: string) => {
if (importedInvitationId) {
setPendingImportedInvitationId(importedInvitationId);
}
setImportingId(null); setImportingId(null);
}, []); }, []);
/**
* Once imported invitation is visible in the list, select and focus it.
*/
useEffect(() => {
if (!pendingImportedInvitationId) return;
const importedIndex = listItems.findIndex((item) => {
return item.value?.data.invitationIdentifier === pendingImportedInvitationId;
});
if (importedIndex >= 0) {
setSelectedIndex(importedIndex);
setFocusedPanel('list');
setPendingImportedInvitationId(null);
}
}, [pendingImportedInvitationId, listItems]);
// ── Action handlers ──────────────────────────────────────────────────── // ── Action handlers ────────────────────────────────────────────────────
const acceptInvitation = useCallback(async () => { const acceptInvitation = useCallback(async () => {

View File

@@ -148,7 +148,7 @@ export function InvitationImportFlow({
`Action: ${invitation?.data.actionIdentifier ?? 'Unknown'}` `Action: ${invitation?.data.actionIdentifier ?? 'Unknown'}`
); );
setStatus('Ready'); setStatus('Ready');
onClose(); onClose(invitation?.data.invitationIdentifier);
}, [selectedRole, template, invitation, showInfo, setStatus, onClose]); }, [selectedRole, template, invitation, showInfo, setStatus, onClose]);
// ── Keyboard handling ──────────────────────────────────────────────────── // ── Keyboard handling ────────────────────────────────────────────────────

View File

@@ -116,8 +116,12 @@ export interface ImportFlowProps {
mode: ImportFlowMode; mode: ImportFlowMode;
/** The application service — injected, not pulled from context. */ /** The application service — injected, not pulled from context. */
appService: AppService; appService: AppService;
/** Called when the flow completes or is cancelled. */ /**
onClose: () => void; * Called when the flow completes or is cancelled.
* When import succeeds, the invitation identifier is provided so callers can
* select/focus the imported invitation in their UI.
*/
onClose: (importedInvitationId?: string) => void;
/** Display an error message to the user. */ /** Display an error message to the user. */
showError: (message: string) => void; showError: (message: string) => void;
/** Display an info message to the user. */ /** Display an info message to the user. */