sadpandajoe commented on code in PR #45591:
URL: https://github.com/apache/superset/pull/45591#discussion_r4367707715


##########
superset-frontend/src/features/groups/utils.ts:
##########
@@ -18,10 +18,75 @@
  */
 import { t } from '@apache-superset/core/translation';
 import { SupersetClient } from '@superset-ui/core';
+import {
+  DEFAULT_SORT_COMPARATOR,
+  type LabeledValue,
+} from '@superset-ui/core/components';
 import rison from 'rison';
+import {
+  SUBJECT_DETAIL_PROP,
+  SUBJECT_OPTION_FILTER_PROPS,
+  SUBJECT_TEXT_LABEL_PROP,
+  SubjectSelectLabel,
+} from 'src/features/subjects/SubjectSelectLabel';
 import { getUserDisplayLabel } from 'src/features/users/utils';
 import { FormValues } from './types';
 
+type UserRecord = { id: number; email?: string } & Parameters<
+  typeof getUserDisplayLabel
+>[0];
+
+/**
+ * Option props AsyncSelect's client-side re-filter should match against for
+ * user options: the display name, the email and the username. These mirror
+ * the columns the server-side `user_all_text` filter searches, so a user the
+ * server matched is never hidden by the picker.
+ */
+export const USER_OPTION_FILTER_PROPS = [
+  ...SUBJECT_OPTION_FILTER_PROPS,
+  'username',
+];
+
+/**
+ * Build a select option for a user picker.
+ *
+ * The option shows the email under the display name, like the subject-based
+ * owner pickers do, so that a server-side match on email is visible to the
+ * person searching. Plain-text copies of both lines, plus the username, are
+ * attached under the `USER_OPTION_FILTER_PROPS` keys so AsyncSelect's
+ * client-side re-filter can match them (a React label is otherwise filtered
+ * as an empty string), and the display name under `title` so ListView can
+ * serialize the chosen option's label into the URL. The username is not
+ * rendered, so a username match surfaces the user without explaining why.
+ */
+export const toUserSelectOption = (user: UserRecord) => {
+  const textLabel = getUserDisplayLabel(user);
+  return {
+    value: user.id,
+    label: SubjectSelectLabel({ label: textLabel, secondaryLabel: user.email 
}),

Review Comment:
   Making `label` a React element also breaks the Select's string-label paths 
beyond paste. Typing a loaded name and then a comma matches against string 
labels, so "Jane Smith," clears the input without selecting Jane (the new title 
fallback only covers clipboard paste, and `reconcileTokensRef` returns early 
when `allowNewOptions` is false). The virtualized option list also builds each 
option's `aria-label` only from a string label, so a screen reader announces 
the numeric user id instead of the name. Would an explicit `aria-label` on the 
option, plus a title-aware token match for these pickers, keep both working?



##########
superset-frontend/src/features/groups/utils.ts:
##########
@@ -47,8 +112,13 @@ export const fetchUserOptions = async (
   pageSize: number,
   addDangerToast: (msg: string) => void,
 ) => {
-  const query = rison.encode({
-    filter: filterValue,
+  // The ListView filter path passes the raw input, so trim here to keep both
+  // callers from sending a whitespace-only search.
+  const searchTerm = filterValue.trim();

Review Comment:
   `searchTerm` is sent to the server with any surrounding double quotes, but 
AsyncSelect's client filter strips them (`stripSurroundingQuotes`). With more 
than one page of users, typing `"Jane Sm"` first shows Jane from the 
already-loaded options, then the server search for the literal `"Jane Sm"` 
returns nothing and replaces the list with an empty result. Should the picker 
strip surrounding quotes before building the `user_all_text` value so both 
sides agree?



-- 
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]

Reply via email to