sfirke opened a new pull request, #45591: URL: https://github.com/apache/superset/pull/45591
### SUMMARY The user pickers in the Roles and Groups modals, and the user filter on the Roles, Groups and Action Log list pages, could not find a user by typing. `fetchUserOptions` sent the search term under a rison `filter` key, which the `/api/v1/security/users/` list endpoint ignores, so every search returned the first page of users in username order. Any user outside that page was unreachable. This PR fixes that in three parts: - **Backend:** registers a `UserSearchFilter` (operator `user_all_text`) on `SupersetUserApi` that matches the search term case-insensitively against username, first name, last name, full name and email. The full name is matched as a whole so "Jane Sm" finds "Jane Smith", and email is included because single sign-on usernames are often opaque identifiers. LIKE metacharacters in the term are escaped with the same `_escape_like` helper the DAO LIKE operators use, so `%` and `_` match literally instead of turning the search into "match everyone". A `None` value matches no rows, mirroring SQL `LIKE NULL` and the DAO operators. Surrounding whitespace is stripped. - **Frontend request:** `fetchUserOptions` sends the term as a `filters` entry with the `user_all_text` operator, trims it first (the ListView filter path passes the raw input, so a whitespace-only search no longer reaches the server), and types the response instead of mapping over `any`. - **Frontend pickers:** user options now show the email under the display name, the way the subject-based owners and editors pickers do, using the shared `SubjectSelectLabel`. Without this, `AsyncSelect`'s client-side re-filter compared the search term against the display name and hid every server-side match on email or username, and a user surfacing for a term that doesn't appear in their name would have looked like a bug. Both modal pickers now re-filter on the option's plain-text name and email props, so email matches are visible and self-explanatory. Design notes: - The filter is registered under the `username` column, which is what the existing pickers already order by. Flask-AppBuilder only attaches a custom search filter when its column is in `search_columns`, so the unit test resolves a `user_all_text` filter through FAB's `Filters` wiring rather than asserting the class attribute, and will fail if `username` is ever removed from `search_columns`. - A blank term sent directly to the API matches every user, the same as FAB's built-in `ct` operator. The frontend omits the filter entirely when the trimmed term is empty. - Username matches are not explained in the option. A user found by typing part of an opaque SSO username shows their name and email, not the username. This is deliberate: showing a third line clutters the picker for a case that mostly serves admins pasting an identifier, and a user with no first or last name already shows their username as the label. - Preselected users in the edit modals are built with the same option helper so they render and filter consistently with search results. ListView's cold-load tooltip label falls back to an option's `title` before its id, since the Users filter options on the list pages now carry a React label. ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF Before: typing a name in the role modal's user picker returns the same first page of users regardless of input. Typing an email returns nothing. After: typing "Jane", "Smith", "jane@" or "Jane Sm" narrows the picker to matching users, and each option shows the email beneath the name. ### TESTING INSTRUCTIONS 1. Create more users than one picker page (100), or pick a user whose username sorts after the first 100 alphabetically. 2. Open Settings → List Roles, edit a role, and type part of that user's first name, last name or email in the Users picker. The user should appear, with their email shown under their name. 3. Type part of their username. The user should appear even though the username is not displayed. 4. Repeat in Settings → List Groups and in the Users filter on the Roles, Groups and Action Log list pages. 5. Type a lone `%` or `_` in the picker. The list should narrow to users whose name or email contains that literal character, not show everyone. 6. Type only spaces. The picker should show the unfiltered first page, not an empty or oddly filtered list. 7. Edit a role or group that already has users. The preselected users should render as before, and searching should still work alongside them. Automated coverage: - `pytest tests/unit_tests/security/user_search_filter_test.py` covers matching across each column, wildcard escaping, whitespace, blank and `None` values, and the FAB filter wiring. - `npm run test -- src/features/groups` covers the request shape, trimming, the blank-term cases, the option builder, and a group modal test that searches by email and expects the user to be listed with their email. That test fails if the picker's `optionFilterProps` is removed. - `npm run test -- src/features/roles/RoleFormItems.test.tsx` has the same email-search regression test for the role modal's Users picker. ### ADDITIONAL INFORMATION <!--- Check any relevant boxes with "x" --> <!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue --> - [ ] Has associated issue: - [ ] Required feature flags: - [x] Changes UI - [ ] Includes DB Migration (follow approval process in [SIP-59](https://github.com/apache/superset/issues/13351)) - [ ] Migration is atomic, supports rollback & is backwards-compatible - [ ] Confirm DB migration upgrade and downgrade tested - [ ] Runtime estimates and downtime expectations provided - [x] Introduces new feature or API - [ ] Removes existing feature or API --- 🤖 _Drafted by Claude Code, reviewed and approved by @sfirke._ -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
