Skip to content

fix(bpm-core-react): show only the latest member search results - #13

Open
coollugi wants to merge 4 commits into
Rytass:mainfrom
coollugi:fix/designer-member-search-results
Open

fix(bpm-core-react): show only the latest member search results#13
coollugi wants to merge 4 commits into
Rytass:mainfrom
coollugi:fix/designer-member-search-results

Conversation

@coollugi

Copy link
Copy Markdown
Contributor

簽核者欄位輸入關鍵字時,下拉清單不會收斂,畫面上永遠列出全部成員

重現

在流程設計器的簽核節點打開「簽核者」,輸入 chen 後等待搜尋完成
後端確實只回傳符合的成員,但下拉仍然列出目錄裡的每一個人

根因

handleSearchMembers 把每次的搜尋結果併入 memberOptions 而不是取代它

setMemberOptions((currentOptions) =>
  mergeMemberOptions(currentOptions, readMemberSelectOptions(options)),
);

而三個 picker 都直接把 memberOptions 當作 options,且都帶 disabledOptionsFilter(前端不再二次過濾)
加上打開下拉時會先以空字串撈一次全部成員,於是畫面顯示的恆等於「目錄全集 ∪ 本次結果」

為什麼不是把 merge 改成取代

memberOptions 同時承擔第二個職責:readMemberSelectOption 用它把 memberId 還原成顯示名稱,
畫布上其他節點的簽核者標籤、節點摘要文字都依賴它
直接改成只保留本次搜尋結果的話,其他節點的簽核者會全部退化成 fallback 標籤,比原本的問題更嚴重

修法

把兩個職責拆開

  • memberOptions 維持累加,繼續作為 id 到顯示名稱的查詢來源
  • 新增 memberSearchResults 只保存最後一次回應
  • 三個 picker 改為 mergeMemberOptions(<各自已選>, memberSearchResults),已選成員仍會留在清單中,不會因為搜尋而失去標籤

同一份改動涵蓋簽核者、無主管時的改派人員、知會對象三處

驗證

項目 結果
pnpm typecheck 6 個 project 全過
pnpm lint--skip-nx-cache 6 個 project 全過,0 error
新增 e2e narrows the approver picker to the latest search result 通過
反向驗證 把本 PR 的修改 stash 後重跑,該測試會失敗(未選中的成員仍留在清單中)

新測試透過 mockTemplateGraphQlextraMembers 選項加入第二位成員
採用 opt-in 參數是為了不改變既有鍵盤操作測試所依賴的選項順序

⚠️ 附帶回報一件與本 PR 無關的事:normalizes legacy approval policy defaults before savingmain 上本身就是失敗的
原因是該測試的 fixture 中,edges 沒有 data 欄位,而 readEdgeSnapshot 直接讀取 edge.data.condition
導致設計器在載入時丟出 Cannot read properties of undefined,整個頁面無法渲染
本 PR 沒有一併處理,供貴方參考

coollugi and others added 4 commits August 11, 2026 23:38
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DVBKX88XEgSHGrxzsL2Zjj
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DVBKX88XEgSHGrxzsL2Zjj
The manager-fallback picker built a "未知會員" sentinel for an empty
memberId and never dropped it, so it appeared as a selectable phantom
row before anyone had picked a fallback member; the same sentinel also
won the merge dedupe over a genuine search hit once a real fallback id
was set. Guard the empty id and merge the search results first so a
real match always wins.

Also guard `memberSearchResults` writes with a sequence ref: typing a
narrower search text while a broader, slower request is still in
flight could let the stale broad response overwrite the newer, correct
one. `memberOptions` accumulation is unaffected since it only ever adds.

Finally, clear `memberSearchResults` synchronously when any picker
opens so the brief window between opening and the fetch landing never
shows a different node's leftover results.
Add a spec for the manager-fallback picker: only the multi-select
approver picker had a narrowing assertion, and the phantom-row defect
lived in the fallback picker instead.

Also add a deterministic regression test for a stale search response
overwriting a newer one. It gates the mocked MemberOptions response so
the test controls resolution order directly instead of racing real
network timing, reproducing the exact race the sequencing fix guards
against.
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.

1 participant