mirror of
https://github.com/apache/superset.git
synced 2026-05-07 08:54:23 +00:00
fix: Incorrect onChange value when an unloaded value is pasted into AsyncSelect (#27996)
(cherry picked from commit 06077d42a8)
This commit is contained in:
committed by
Michael S. Molina
parent
83b4947ad2
commit
ffe87bf2ec
@@ -384,12 +384,14 @@ test('removes duplicated values', async () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
fireEvent(input, paste);
|
fireEvent(input, paste);
|
||||||
const values = await findAllSelectValues();
|
await waitFor(async () => {
|
||||||
expect(values.length).toBe(4);
|
const values = await findAllSelectValues();
|
||||||
expect(values[0]).toHaveTextContent('a');
|
expect(values.length).toBe(4);
|
||||||
expect(values[1]).toHaveTextContent('b');
|
expect(values[0]).toHaveTextContent('a');
|
||||||
expect(values[2]).toHaveTextContent('c');
|
expect(values[1]).toHaveTextContent('b');
|
||||||
expect(values[3]).toHaveTextContent('d');
|
expect(values[2]).toHaveTextContent('c');
|
||||||
|
expect(values[3]).toHaveTextContent('d');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders a custom label', async () => {
|
test('renders a custom label', async () => {
|
||||||
@@ -879,7 +881,7 @@ test('fires onChange when pasting a selection', async () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
fireEvent(input, paste);
|
fireEvent(input, paste);
|
||||||
expect(onChange).toHaveBeenCalledTimes(1);
|
await waitFor(() => expect(onChange).toHaveBeenCalledTimes(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('does not duplicate options when using numeric values', async () => {
|
test('does not duplicate options when using numeric values', async () => {
|
||||||
@@ -935,8 +937,30 @@ test('pasting an existing option does not duplicate it in multiple mode', async
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
fireEvent(input, paste);
|
fireEvent(input, paste);
|
||||||
// Only Peter should be added
|
await waitFor(async () =>
|
||||||
expect(await findAllSelectOptions()).toHaveLength(4);
|
// Only Peter should be added
|
||||||
|
expect(await findAllSelectOptions()).toHaveLength(4),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('onChange is called with the value property when pasting an option that was not loaded yet', async () => {
|
||||||
|
const onChange = jest.fn();
|
||||||
|
render(<AsyncSelect {...defaultProps} onChange={onChange} />);
|
||||||
|
await open();
|
||||||
|
const input = getElementByClassName('.ant-select-selection-search-input');
|
||||||
|
const lastOption = OPTIONS[OPTIONS.length - 1];
|
||||||
|
const paste = createEvent.paste(input, {
|
||||||
|
clipboardData: {
|
||||||
|
getData: () => lastOption.label,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
fireEvent(input, paste);
|
||||||
|
await waitFor(() =>
|
||||||
|
expect(onChange).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ value: lastOption.value }),
|
||||||
|
expect.anything(),
|
||||||
|
),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('does not fire onChange if the same value is selected in single mode', async () => {
|
test('does not fire onChange if the same value is selected in single mode', async () => {
|
||||||
|
|||||||
@@ -537,8 +537,15 @@ const AsyncSelect = forwardRef(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const getPastedTextValue = useCallback(
|
const getPastedTextValue = useCallback(
|
||||||
(text: string) => {
|
async (text: string) => {
|
||||||
const option = getOption(text, fullSelectOptions, true);
|
let option = getOption(text, fullSelectOptions, true);
|
||||||
|
if (!option && !allValuesLoaded) {
|
||||||
|
const fetchOptions = options as SelectOptionsPagePromise;
|
||||||
|
option = await fetchOptions(text, 0, pageSize).then(
|
||||||
|
({ data }: SelectOptionsTypePage) =>
|
||||||
|
data.find(item => item.label === text),
|
||||||
|
);
|
||||||
|
}
|
||||||
const value: AntdLabeledValue = {
|
const value: AntdLabeledValue = {
|
||||||
label: text,
|
label: text,
|
||||||
value: text,
|
value: text,
|
||||||
@@ -549,20 +556,22 @@ const AsyncSelect = forwardRef(
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
[fullSelectOptions],
|
[allValuesLoaded, fullSelectOptions, options, pageSize],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onPaste = (e: ClipboardEvent<HTMLInputElement>) => {
|
const onPaste = async (e: ClipboardEvent<HTMLInputElement>) => {
|
||||||
const pastedText = e.clipboardData.getData('text');
|
const pastedText = e.clipboardData.getData('text');
|
||||||
if (isSingleMode) {
|
if (isSingleMode) {
|
||||||
setSelectValue(getPastedTextValue(pastedText));
|
setSelectValue(await getPastedTextValue(pastedText));
|
||||||
} else {
|
} else {
|
||||||
const token = tokenSeparators.find(token => pastedText.includes(token));
|
const token = tokenSeparators.find(token => pastedText.includes(token));
|
||||||
const array = token ? uniq(pastedText.split(token)) : [pastedText];
|
const array = token ? uniq(pastedText.split(token)) : [pastedText];
|
||||||
const values = array.map(item => getPastedTextValue(item));
|
const values = await Promise.all(
|
||||||
|
array.map(item => getPastedTextValue(item)),
|
||||||
|
);
|
||||||
setSelectValue(previous => [
|
setSelectValue(previous => [
|
||||||
...((previous || []) as AntdLabeledValue[]),
|
...((previous || []) as AntdLabeledValue[]),
|
||||||
...values,
|
...values.filter(value => !hasOption(value.value, previous)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
fireOnChange();
|
fireOnChange();
|
||||||
|
|||||||
Reference in New Issue
Block a user