Nonclick untile load complete
parent
d00ebcf6f5
commit
5cc1dc1997
|
|
@ -1389,6 +1389,9 @@ export default function Inbox() {
|
|||
queryFn: () => (selectedKind === 'form' ? fetchFormDetail(selectedId) : fetchMessageDetail(selectedId)),
|
||||
enabled: Boolean(selectedId),
|
||||
})
|
||||
// List rows paint immediately; GET-by-id is the full application. Block every
|
||||
// control in the detail pane until that fetch succeeds. The queue stays live.
|
||||
const detailLocked = Boolean(selectedId) && !detailQuery.isError && !detailQuery.isSuccess
|
||||
|
||||
const sidebar = useMemo(() => {
|
||||
if (!isForms) return list
|
||||
|
|
@ -1959,12 +1962,18 @@ export default function Inbox() {
|
|||
{friendlyAuthError(detailQuery.error, 'Request failed')}
|
||||
</EmptyState>
|
||||
</div>
|
||||
) : selected?.kind === 'form' ? (
|
||||
) : (
|
||||
<div
|
||||
className={detailLocked ? 'inbox-detail-pending' : undefined}
|
||||
inert={detailLocked || undefined}
|
||||
aria-busy={detailLocked || undefined}
|
||||
>
|
||||
{selected?.kind === 'form' ? (
|
||||
<FormApplicantDetail
|
||||
item={selected}
|
||||
loading={detailQuery.isPending}
|
||||
busy={setState.isPending || markDuplicate.isPending}
|
||||
canEdit={canEdit}
|
||||
loading={detailLocked}
|
||||
busy={detailLocked || setState.isPending || markDuplicate.isPending}
|
||||
canEdit={!detailLocked && canEdit}
|
||||
toast={toast}
|
||||
onImport={() => importItem(selected)}
|
||||
onMove={() => moveToPipeline(selected)}
|
||||
|
|
@ -1975,9 +1984,9 @@ export default function Inbox() {
|
|||
) : (
|
||||
<ApplicationDetail
|
||||
item={selected}
|
||||
loading={detailQuery.isPending}
|
||||
busy={setState.isPending || markDuplicate.isPending}
|
||||
canEdit={canEdit}
|
||||
loading={detailLocked}
|
||||
busy={detailLocked || setState.isPending || markDuplicate.isPending}
|
||||
canEdit={!detailLocked && canEdit}
|
||||
toast={toast}
|
||||
onImport={() => importItem(selected)}
|
||||
onMove={() => moveToPipeline(selected)}
|
||||
|
|
@ -1987,6 +1996,8 @@ export default function Inbox() {
|
|||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1032,6 +1032,14 @@ canvas { width: 100%; max-width: 100%; display: block; }
|
|||
.inbox-split { grid-template-columns: minmax(280px, 34%) minmax(0, 1fr); }
|
||||
/* Desktop keeps the two-pane split; only the phone layout below shows it. */
|
||||
.inbox-back { display: none; }
|
||||
/* Detail pane is painted from the list row before GET-by-id returns. Block
|
||||
every control inside it until that payload lands — the queue list stays live. */
|
||||
.inbox-detail-pending {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
opacity: 0.55;
|
||||
cursor: wait;
|
||||
}
|
||||
/* Phones: the stacked split nested two scroll wells inside the page scroll.
|
||||
Instead: one page scroll, and a selected application takes over from the
|
||||
list — the Back button returns to it (standard master-detail collapse). */
|
||||
|
|
|
|||
Loading…
Reference in New Issue