This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-5756-cc94414e6059944d304c7c85e9cebe03d6a2453d in repository https://gitbox.apache.org/repos/asf/texera.git
commit ca6e8e90e298695e1f74b33bec282a0b80f9dbcb Author: anthonychengit <[email protected]> AuthorDate: Tue Jun 23 18:47:23 2026 -0700 fix(frontend): improve admin user search (#5756) ### What changes were proposed in this PR? This PR improves Admin Users search behavior consistency. Changes: - Normalize active search values by trimming whitespace before filtering. - Make email and comment search case-insensitive. - Clear inactive search fields when applying a different Admin Users search filter. - Add focused component tests for email/comment search, trimming, and inactive search-field clearing. ### Any related issues, documentation, discussions? Related to #3589 ### How was this PR tested? Tested with: - `node .yarn/releases/yarn-4.14.1.cjs prettier --check src/app/dashboard/component/admin/user/admin-user.component.ts src/app/dashboard/component/admin/user/admin-user.component.spec.ts` - `node .yarn/releases/yarn-4.14.1.cjs eslint src/app/dashboard/component/admin/user/admin-user.component.ts src/app/dashboard/component/admin/user/admin-user.component.spec.ts` - `node .yarn/releases/yarn-4.14.1.cjs test --include=src/app/dashboard/component/admin/user/admin-user.component.spec.ts` ### Was this PR authored or co-authored using generative AI tooling? Generated-by: ChatGPT was used for planning and review assistance. I reviewed and tested the final code before submission. --- .../admin/user/admin-user.component.spec.ts | 109 +++++++++++++++++++++ .../component/admin/user/admin-user.component.ts | 26 ++++- 2 files changed, 131 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/dashboard/component/admin/user/admin-user.component.spec.ts b/frontend/src/app/dashboard/component/admin/user/admin-user.component.spec.ts index ff5ef8cf39..f3568bf254 100644 --- a/frontend/src/app/dashboard/component/admin/user/admin-user.component.spec.ts +++ b/frontend/src/app/dashboard/component/admin/user/admin-user.component.spec.ts @@ -48,4 +48,113 @@ describe("AdminUserComponent", () => { it("should create", inject([HttpTestingController], () => { expect(component).toBeTruthy(); })); + + it("should search email case-insensitively", () => { + component.userList = [ + { + name: "Alice", + email: "[email protected]", + comment: "Needs review", + } as any, + { + name: "Bob", + email: "[email protected]", + comment: "Approved", + } as any, + ]; + + component.emailSearchValue = "[email protected]"; + component.searchByEmail(); + + expect(component.listOfDisplayUser.length).toBe(1); + expect(component.listOfDisplayUser[0].email).toBe("[email protected]"); + }); + + it("should search comment case-insensitively", () => { + component.userList = [ + { + name: "Alice", + email: "[email protected]", + comment: "Needs review", + } as any, + { + name: "Bob", + email: "[email protected]", + comment: "Approved", + } as any, + ]; + + component.commentSearchValue = "NEEDS REVIEW"; + component.searchByComment(); + + expect(component.listOfDisplayUser.length).toBe(1); + expect(component.listOfDisplayUser[0].comment).toBe("Needs review"); + }); + + it("should trim active email search value without lowercasing the stored input", () => { + component.userList = [ + { + name: "Alice", + email: "[email protected]", + comment: "Needs review", + } as any, + ]; + + component.emailSearchValue = " [email protected] "; + component.searchByEmail(); + + expect(component.emailSearchValue).toBe("[email protected]"); + expect(component.listOfDisplayUser.length).toBe(1); + expect(component.listOfDisplayUser[0].email).toBe("[email protected]"); + }); + + it("should trim active comment search value without lowercasing the stored input", () => { + component.userList = [ + { + name: "Alice", + email: "[email protected]", + comment: "Needs review", + } as any, + ]; + + component.commentSearchValue = " Needs review "; + component.searchByComment(); + + expect(component.commentSearchValue).toBe("Needs review"); + expect(component.listOfDisplayUser.length).toBe(1); + expect(component.listOfDisplayUser[0].comment).toBe("Needs review"); + }); + + it("should clear inactive search values when searching by name", () => { + component.emailSearchValue = "[email protected]"; + component.commentSearchValue = "Needs review"; + + component.nameSearchValue = "Alice"; + component.searchByName(); + + expect(component.emailSearchValue).toBe(""); + expect(component.commentSearchValue).toBe(""); + }); + + it("should clear inactive search values when searching by email", () => { + component.nameSearchValue = "Alice"; + component.commentSearchValue = "Needs review"; + + component.emailSearchValue = "[email protected]"; + component.searchByEmail(); + + expect(component.nameSearchValue).toBe(""); + expect(component.commentSearchValue).toBe(""); + }); + + it("should clear inactive search values when searching by comment", () => { + component.nameSearchValue = "Alice"; + component.emailSearchValue = "[email protected]"; + + component.commentSearchValue = "Approved"; + component.searchByComment(); + + expect(component.nameSearchValue).toBe(""); + expect(component.emailSearchValue).toBe(""); + }); }); diff --git a/frontend/src/app/dashboard/component/admin/user/admin-user.component.ts b/frontend/src/app/dashboard/component/admin/user/admin-user.component.ts index 0d7f620480..c6758f88df 100644 --- a/frontend/src/app/dashboard/component/admin/user/admin-user.component.ts +++ b/frontend/src/app/dashboard/component/admin/user/admin-user.component.ts @@ -288,20 +288,38 @@ export class AdminUserComponent implements OnInit { this.listOfDisplayUser = [...this.userList]; } + private trimSearchValue(value: string | null | undefined): string { + return (value ?? "").trim(); + } + searchByName(): void { this.nameSearchVisible = false; - const q = (this.nameSearchValue ?? "").trim().toLowerCase(); - this.listOfDisplayUser = this.userList.filter(u => (u.name ?? "").toLowerCase().includes(q)); + this.nameSearchValue = this.trimSearchValue(this.nameSearchValue); + this.emailSearchValue = ""; + this.commentSearchValue = ""; + + const q = this.nameSearchValue.toLowerCase(); + this.listOfDisplayUser = this.userList.filter(user => (user.name ?? "").toLowerCase().includes(q)); } searchByEmail(): void { this.emailSearchVisible = false; - this.listOfDisplayUser = this.userList.filter(user => (user.email || "").indexOf(this.emailSearchValue) !== -1); + this.emailSearchValue = this.trimSearchValue(this.emailSearchValue); + this.nameSearchValue = ""; + this.commentSearchValue = ""; + + const q = this.emailSearchValue.toLowerCase(); + this.listOfDisplayUser = this.userList.filter(user => (user.email ?? "").toLowerCase().includes(q)); } searchByComment(): void { this.commentSearchVisible = false; - this.listOfDisplayUser = this.userList.filter(user => (user.comment || "").indexOf(this.commentSearchValue) !== -1); + this.commentSearchValue = this.trimSearchValue(this.commentSearchValue); + this.nameSearchValue = ""; + this.emailSearchValue = ""; + + const q = this.commentSearchValue.toLowerCase(); + this.listOfDisplayUser = this.userList.filter(user => (user.comment ?? "").toLowerCase().includes(q)); } clickToViewQuota(uid: number) {
