codeant-ai-for-open-source[bot] commented on code in PR #39068:
URL: https://github.com/apache/superset/pull/39068#discussion_r3531270147


##########
superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx:
##########
@@ -268,6 +278,8 @@ const AsyncSelect = forwardRef(
           }
           return previousState;
         });
+        setInputValue('');

Review Comment:
   **Suggestion:** This unconditionally clears the search input in multi-select 
mode, which bypasses the `autoClearSearchValue` prop contract and changes 
behavior for callers that intentionally disable auto-clearing. Only clear the 
input when `autoClearSearchValue` is true. [api mismatch]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   ⚠️ Multi-select AsyncSelect ignores autoClearSearchValue=false configuration.
   ⚠️ Search text cannot be preserved across selections when desired.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Review the multi-select selection handler in
   
`superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx:137-173`,
   where the `else` branch of `handleOnSelect` (triggered when `mode !== 
'single'`) appends
   the new selection to `selectValue`.
   
   2. In that multi-select branch, immediately after updating `selectValue`, 
the code calls
   `setInputValue('');` at `AsyncSelect.tsx:281` and then 
`setSelectOptions(prev =>
   prev.sort(sortComparatorForNoSearch));`, clearing the controlled 
`inputValue` state
   regardless of the `autoClearSearchValue` prop.
   
   3. Beneath this block, a separate `if (autoClearSearchValue) { 
setInputValue(''); ... }`
   conditional at `AsyncSelect.tsx:166-171` is meant to honor the caller’s
   `autoClearSearchValue` configuration (for example, 
`SelectFilterPlugin.tsx:610-36` passes
   `autoClearSearchValue` when using the related Select wrapper), but in 
AsyncSelect’s
   multi-select path the earlier unconditional `setInputValue('');` has already 
cleared the
   search text even when `autoClearSearchValue` is `false`.
   
   4. If a caller configures AsyncSelect in multi-select mode with
   `autoClearSearchValue={false}` (e.g. by extending the existing multi-select 
usages in
   `AccessSection.tsx:11-25` to keep search text after selection), they will 
still see the
   search input cleared on every selection because of the unconditional call at 
line 281,
   violating the expected API contract that `autoClearSearchValue` controls 
whether the input
   is cleared.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=fb7e08aac4d749c2a340e37958fd5a44&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=fb7e08aac4d749c2a340e37958fd5a44&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx
   **Line:** 281:281
   **Comment:**
        *Api Mismatch: This unconditionally clears the search input in 
multi-select mode, which bypasses the `autoClearSearchValue` prop contract and 
changes behavior for callers that intentionally disable auto-clearing. Only 
clear the input when `autoClearSearchValue` is true.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39068&comment_hash=a7cd86e308c0a063de1b0dc5100bdd8bd8ceb72ac73022318a584c9eea80b974&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39068&comment_hash=a7cd86e308c0a063de1b0dc5100bdd8bd8ceb72ac73022318a584c9eea80b974&reaction=dislike'>👎</a>



##########
superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx:
##########
@@ -268,6 +278,8 @@ const AsyncSelect = forwardRef(
           }
           return previousState;
         });
+        setInputValue('');
+        setSelectOptions(prev => prev.sort(sortComparatorForNoSearch));

Review Comment:
   **Suggestion:** The state update sorts `prev` in place and returns the same 
array reference, which mutates React state directly and can prevent a re-render 
because the reference does not change. Sort a copied array instead so state 
remains immutable and updates are reliably rendered. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   ⚠️ Multi-select option order updates may not re-render.
   ⚠️ Direct state mutation risks subtle React rendering bugs.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open the dashboard properties modal and navigate to the access section, 
which renders
   the multi-select AsyncSelect for owners at
   `src/dashboard/components/PropertiesModal/sections/AccessSection.tsx:11-25` 
with
   `mode="multiple"` and `showSearch`.
   
   2. In the owners AsyncSelect, select several owner values so the control is 
populated;
   this triggers `handleOnSelect` in `AsyncSelect.tsx:137-173`, which in 
multi-select mode
   appends the selected item to `selectValue` and then executes 
`setSelectOptions(prev =>
   prev.sort(sortComparatorForNoSearch));` at `AsyncSelect.tsx:150-164`.
   
   3. Click again on an already-selected owner value so that 
`setSelectValue(previousState =>
   { ... })` returns `previousState` unchanged (duplicate selection branch at
   `AsyncSelect.tsx:150-160`), meaning React will see no change in 
`selectValue`; the
   subsequent `setSelectOptions(prev => prev.sort(...))` mutates the `prev` 
array in place
   and returns the same reference.
   
   4. Because React compares the previous and next state by reference, 
`setSelectOptions`
   receives `prev` and returns the identical array reference (only mutated in 
place), so it
   can bail out of re-rendering; option ordering changes from the in-place 
`.sort` may not be
   reflected until some unrelated state change re-renders the component, 
demonstrating direct
   state mutation and potentially missed UI updates.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=1ac4742983634829922420656683e25e&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=1ac4742983634829922420656683e25e&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx
   **Line:** 282:282
   **Comment:**
        *Logic Error: The state update sorts `prev` in place and returns the 
same array reference, which mutates React state directly and can prevent a 
re-render because the reference does not change. Sort a copied array instead so 
state remains immutable and updates are reliably rendered.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39068&comment_hash=bde29478b5cd484b08643d02529941b0513efe192d4b4adbbdaaa66464f66bc4&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39068&comment_hash=bde29478b5cd484b08643d02529941b0513efe192d4b4adbbdaaa66464f66bc4&reaction=dislike'>👎</a>



##########
superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx:
##########
@@ -693,15 +760,8 @@ const AsyncSelect = forwardRef(
           setSelectValue(value);
         }
       } else {
-        const token = tokenSeparators.find(token => 
pastedText.includes(token));
-        const array = token
-          ? uniq(
-              pastedText
-                .split(token)
-                .map(s => s.trim())
-                .filter(Boolean),
-            )
-          : [pastedText.trim()].filter(Boolean);
+        e.preventDefault();
+        const array = uniq(splitWithQuoteEscaping(pastedText, 
tokenSeparators));
         const values = (

Review Comment:
   **Suggestion:** `splitWithQuoteEscaping` only applies one separator, but 
this call passes the full `tokenSeparators` list; pasted text containing mixed 
delimiters (for example comma plus newline/tab) will be split incorrectly into 
merged tokens. Tokenize across all configured separators with quote awareness 
instead of using a single-separator split. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   ⚠️ Multi-value paste in AsyncSelect misparses CSV-style text.
   ⚠️ Newline-separated quoted values merge into single incorrect token.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open the dashboard access modal and use the owners AsyncSelect at
   `src/dashboard/components/PropertiesModal/sections/AccessSection.tsx:11-25`, 
which is
   configured with `mode="multiple"` and `showSearch`, and uses the shared 
AsyncSelect
   implementation from `AsyncSelect.tsx`.
   
   2. In that multi-select AsyncSelect, paste CSV-like text where each value 
may contain
   commas and rows are separated by newlines, e.g. `"Australia, 
Austria"\n"Canada, US"`, into
   the input; this invokes the `onPaste` handler defined at 
`AsyncSelect.tsx:118-135`, where
   the multi-select branch (`!isSingleMode`) prevents default paste and 
computes `const array
   = uniq(splitWithQuoteEscaping(pastedText, tokenSeparators));`.
   
   3. Inspect `splitWithQuoteEscaping` in
   
`superset-frontend/packages/superset-ui-core/src/components/Select/utils.tsx:67-99`,
 which
   takes a `separators: string[]` but chooses only the first separator present 
via `const
   separator = separators.find(sep => text.includes(sep));` and then splits 
exclusively on
   that one token; the shared `TOKEN_SEPARATORS` are `[' ,', '\r\n', '\n', 
'\t', ';']` as
   defined in `constants.ts:26`, so any pasted text containing both commas and 
newlines will
   always select `','` as the separator and ignore `\n` and other delimiters.
   
   4. As a result, the owners AsyncSelect will split the sample text by commas 
only
   (preserving quoted commas but ignoring newlines), producing merged tokens 
like
   `"Australia, Austria"` and `"Canada\nUS"` instead of separate 
newline-delimited values;
   the filter sees fewer tokens than expected and cannot generate one chip per 
row, breaking
   the documented behavior for pasting multi-value lists with quotes and mixed 
delimiters.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=a3683b935ceb4561ab68a897e1988e8d&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=a3683b935ceb4561ab68a897e1988e8d&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx
   **Line:** 765:765
   **Comment:**
        *Logic Error: `splitWithQuoteEscaping` only applies one separator, but 
this call passes the full `tokenSeparators` list; pasted text containing mixed 
delimiters (for example comma plus newline/tab) will be split incorrectly into 
merged tokens. Tokenize across all configured separators with quote awareness 
instead of using a single-separator split.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39068&comment_hash=04ed3d859c03aad99f48dd76d0ce411cb2f6699b7249e7fa488b2ff6ffcb74cc&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39068&comment_hash=04ed3d859c03aad99f48dd76d0ce411cb2f6699b7249e7fa488b2ff6ffcb74cc&reaction=dislike'>👎</a>



##########
superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx:
##########
@@ -767,7 +827,7 @@ const AsyncSelect = forwardRef(
           // surface, but the underlying input accepts it and we rely on that.
           onPaste={onPaste}
           onPopupScroll={handlePagination}
-          onSearch={showSearch ? handleOnSearch : undefined}
+          onSearch={showSearch ? onSearchChange : undefined}

Review Comment:
   **Suggestion:** The search handler is disabled when `showSearch` is false, 
but search is still force-enabled when new options are allowed; with controlled 
`searchValue`, typing will not update input state in that configuration. Use 
the same condition for `onSearch` as for `showSearch` so searchable mode always 
has an input-change handler. [api mismatch]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   ⚠️ Future free-form AsyncSelect configs may ignore keystrokes.
   ⚠️ Search input can appear but never update internal state.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Inspect `AsyncSelect` props and wiring in
   
`superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx:77-115`,
   where `allowNewOptions`, `showSearch` and `onSearch` are accepted, and the 
internal
   `inputValue` state is bound to the select via `searchValue={inputValue}` at
   `AsyncSelect.tsx:204-205`.
   
   2. Observe that the underlying antd Select is configured with 
`showSearch={allowNewOptions
   ? true : showSearch}` at `AsyncSelect.tsx:204`, forcing the search input 
visible whenever
   `allowNewOptions` is true, even if the caller passes `showSearch={false}`.
   
   3. At `AsyncSelect.tsx:193`, the search handler is wired as 
`onSearch={showSearch ?
   onSearchChange : undefined}`, using the raw `showSearch` prop rather than 
the effective
   `showSearch` value passed to the Select; therefore, in any component that 
sets
   `allowNewOptions={true}` and `showSearch={false}` (for example, by updating 
the existing
   usage in `src/explore/components/SaveModal.tsx:14-29` that currently passes
   `allowNewOptions` without `showSearch`), the input will be visible but 
`onSearch` will be
   `undefined`.
   
   4. In that configuration, typing into the visible search box will not update 
`inputValue`
   or trigger `runSearchLogic` (which depends on `onSearchChange` at
   `AsyncSelect.tsx:153-172`), so free-form entry and search callbacks break 
even though the
   input is shown, demonstrating a real API mismatch between the `showSearch` 
and `onSearch`
   wiring.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=9084d0ff7ce94111a22868b9479279d6&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=9084d0ff7ce94111a22868b9479279d6&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** 
superset-frontend/packages/superset-ui-core/src/components/Select/AsyncSelect.tsx
   **Line:** 830:830
   **Comment:**
        *Api Mismatch: The search handler is disabled when `showSearch` is 
false, but search is still force-enabled when new options are allowed; with 
controlled `searchValue`, typing will not update input state in that 
configuration. Use the same condition for `onSearch` as for `showSearch` so 
searchable mode always has an input-change handler.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39068&comment_hash=df91934eedf2793ef1f915b3868857e77a8c5273b4489d358df99f71186b1c0c&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F39068&comment_hash=df91934eedf2793ef1f915b3868857e77a8c5273b4489d358df99f71186b1c0c&reaction=dislike'>👎</a>



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