Skip to content

fix(org-workbench): keep stale employee panels on switch (#413) - #417

Merged
PeterGuy326 merged 1 commit into
mainfrom
fix/413-employee-switch-flash
Sep 20, 2026
Merged

PeterGuy326 merged 1 commit into
mainfrom
fix/413-employee-switch-flash

Conversation

@sun-970

@sun-970 sun-970 commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #413: switching employees in the org workbench no longer flashes both the center PositionCard and the right TurnPanel to skeletons, stacks empty-state on the loading thread, or crossfades two tree-row highlights.

What changed

  • loadPosition keeps the previous card.data while loading is true; PositionCard only skeletons when there is no record yet.
  • Employee switch no longer setTurns([]) before the next history arrives; a null session during attach no longer wipes the current thread.
  • TurnThread does not mount the empty-state node while loading; CSS .owb-turn-thread--empty[hidden] { display: none } covers the display:flex vs [hidden] override.
  • Org tree rows no longer transition background, so selected fill moves in one frame.

Tests

  • packages/ui PositionCard stale-while-loading + org-tree CSS contract
  • TurnPanel loading does not keep .ui-org-empty-state in the DOM
  • App A→B with B's position() in flight keeps A's card heading and thread
  • renderer-css-syntax asserts the [hidden] rule

npm run test:ui (40), App.test.tsx (86), TurnPanel.test.tsx (28), renderer-css-syntax.test.cjs (3).

Acceptance (#413)

  • A→B does not full-panel skeleton if A was already on screen
  • Loading skeleton and empty-state are not both in the DOM
  • .owb-panel shell no longer collapses to a 4-row skeleton over stale content
  • Selected tree fill is not a 120ms crossfade
  • First selection with no record still skeletons

@waterbro-8 waterbro-8 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REQUEST_CHANGES,head 4abc1705。方向对(stale-while-revalidate + 空态不跟 skeleton 叠),但现在不能批。

  • CONFLICTING/DIRTY: base 停在 #414(6e26755a),#410 已经进 main(f5e9af18)。多半是 CHANGELOG 同一处。请 rebase 到最新 main。我推不了你的分支。
  • sessionId === null 不再 setTurns([]): 切到还没有 session 的员工 B 时,A 的线程会一直留在 B 的面板上。stale-while-revalidate 只应持续到 B 的 history/空 session 有结果;确认 B 无 session 后要清掉 A 的 turns(按 selectedId 盖戳也行)。
  • CI 还没跑。rebase 后等绿再叫我复审。非产品验收。

@sun-970
sun-970 force-pushed the fix/413-employee-switch-flash branch from 4abc170 to c100f94 Compare September 20, 2026 10:31
@sun-970

sun-970 commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased onto current main 6e26755 (#414). CHANGELOG keeps both #412 and #413.

loadSessions now setTurns([]) once this employee is confirmed to have no session (or the sessions read fails). Stale-while-revalidate still holds while attach is in flight. Added #413 clears employee A's thread once B is confirmed to have no session.

#410 (f5e9af18) is merged to feat/402-multi-party-approval-policy, not main.

@sun-970
sun-970 requested a review from waterbro-8 September 20, 2026 10:42
Stop blanking PositionCard and TurnThread into skeletons when selecting
another employee. Keep the previous record/thread until the new payload
arrives, hide the empty-state node while loading, and drop the tree
selected-fill crossfade so two rows cannot glow at once.

Once the target employee is confirmed to have no session, drop the
previous thread so it cannot remain on the new panel.
@sun-970
sun-970 force-pushed the fix/413-employee-switch-flash branch from c100f94 to 37b4b33 Compare September 20, 2026 10:43

@waterbro-8 waterbro-8 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review APPROVE (not product 验收), head 37b4b33d.

Rebase onto current main looks clean (CHANGELOG keeps #412 and #413). Confirmed-empty session now setTurns([]) after the sessions read (and on sessions fail / offline), so employee A's thread does not stick on B. Tests cover in-flight stale card/thread and the no-session clear. CI 11/11 green.

Not product 验收. 胡奕舟 can merge.

@PeterGuy326 PeterGuy326 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at head 37b4b33d. Read the full diff and traced the state transitions in App.tsx at this head.

Verified in code:

  • loadPosition keeps prev.data only while loading; every terminal path still overwrites it (404 / position_missing → notFound: true, non-200 → data: null, catch → data: null), so a failed fetch cannot pin employee A's record on B's panel.
  • The three removed setTurns([]) calls are covered by loadSessions: the confirmed-empty session branch, the non-200 sessions branch, and the offline catch all clear turns and historyLoading, each guarded by selectionVersion + selectedIdRef. A late read for A therefore cannot wipe B, and loadTurnHistory returning early on sessionId === null without clearing is safe.
  • selectPosition bumps selectionVersion before the stale window opens, which is what keeps A's in-flight reads inert.
  • .owb-turn-thread--empty[hidden] { display: none } is load-bearing rather than dead CSS: the author rule sets display: flex on --empty, which beats the UA [hidden] { display: none }, and the <ol> still carries both the --empty class and hidden. The new selector wins on specificity (0,2,0 vs 0,1,0) and on source order.
  • Dropping transition: background from .ui-org-tree__row makes the prefers-reduced-motion override redundant, so removing that block is consistent.

Non-blocking, worth a follow-up: during the stale window selectedPosition is still A's record while selectedId is already B, and the actions slot mixes the two — DismissPositionDialog renders selectedPosition.name (A) alongside selectedNode's descendant count (B) and calls dismissPosition(selectedId) (B). The window is a single local position() round trip, so it is not realistically clickable today, but the label/target split is the kind of thing that bites later. Fine to land as-is.

CI 11/11 green on this head. waterbro-8's approval covers the rebase and the no-session clear; my pass was a diff + source read, I did not re-run the renderer suites locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(org-workbench): switching employees flashes skeleton panels, ghost card outline, and hard-cuts with no transition

3 participants