fix: Change multiselect back to supporting numbers and boolean. (#7895)
* Revert "fix: multiselect validation (#7698)"
This reverts commit 728a2559c5.
* - Convert the multiselect options value and labels to string before filtering as the values can be numbers.
* - Discourage users from using string in multiselect default value
Co-authored-by: Satish Gandham <satish@appsmith.com>
This commit is contained in:
parent
883b0215a6
commit
c3d5b1010b
|
|
@ -99,10 +99,16 @@ function MultiSelectComponent({
|
||||||
[isSelectAll, options, loading],
|
[isSelectAll, options, loading],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Convert the values to string before searching.
|
||||||
|
// input is always a string.
|
||||||
const filterOption = useCallback(
|
const filterOption = useCallback(
|
||||||
(input, option) =>
|
(input, option) =>
|
||||||
option?.props.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
|
String(option?.props.label)
|
||||||
option?.props.value.toLowerCase().indexOf(input.toLowerCase()) >= 0,
|
.toLowerCase()
|
||||||
|
.indexOf(input.toLowerCase()) >= 0 ||
|
||||||
|
String(option?.props.value)
|
||||||
|
.toLowerCase()
|
||||||
|
.indexOf(input.toLowerCase()) >= 0,
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ class MultiSelectWidget extends BaseWidget<
|
||||||
name: "label",
|
name: "label",
|
||||||
type: ValidationTypes.TEXT,
|
type: ValidationTypes.TEXT,
|
||||||
params: {
|
params: {
|
||||||
|
default: "",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -78,6 +79,7 @@ class MultiSelectWidget extends BaseWidget<
|
||||||
name: "value",
|
name: "value",
|
||||||
type: ValidationTypes.TEXT,
|
type: ValidationTypes.TEXT,
|
||||||
params: {
|
params: {
|
||||||
|
default: "",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -94,7 +96,7 @@ class MultiSelectWidget extends BaseWidget<
|
||||||
propertyName: "defaultOptionValue",
|
propertyName: "defaultOptionValue",
|
||||||
label: "Default Value",
|
label: "Default Value",
|
||||||
controlType: "INPUT_TEXT",
|
controlType: "INPUT_TEXT",
|
||||||
placeholderText: "GREEN",
|
placeholderText: "[GREEN]",
|
||||||
isBindProperty: true,
|
isBindProperty: true,
|
||||||
isTriggerProperty: false,
|
isTriggerProperty: false,
|
||||||
validation: {
|
validation: {
|
||||||
|
|
@ -102,8 +104,8 @@ class MultiSelectWidget extends BaseWidget<
|
||||||
params: {
|
params: {
|
||||||
fn: defaultOptionValueValidation,
|
fn: defaultOptionValueValidation,
|
||||||
expected: {
|
expected: {
|
||||||
type: "value or Array of values",
|
type: "Array of values",
|
||||||
example: `option1 | ['option1', 'option2']`,
|
example: `['option1', 'option2']`,
|
||||||
autocompleteDataType: AutocompleteDataType.ARRAY,
|
autocompleteDataType: AutocompleteDataType.ARRAY,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -962,229 +962,6 @@ describe("Validate Validators", () => {
|
||||||
expect(result).toStrictEqual(expected);
|
expect(result).toStrictEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("correctly validates objects", () => {
|
|
||||||
const inputs = [
|
|
||||||
{
|
|
||||||
label: true,
|
|
||||||
value: "true",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: true,
|
|
||||||
value: "true",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
paletteColors1: "#ffffff",
|
|
||||||
palettecolors2: "#ffffff",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const config = [
|
|
||||||
{
|
|
||||||
type: ValidationTypes.OBJECT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
allowedKeys: [
|
|
||||||
{
|
|
||||||
name: "label",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "value",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: ValidationTypes.OBJECT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
allowedKeys: [
|
|
||||||
{
|
|
||||||
name: "label",
|
|
||||||
type: ValidationTypes.BOOLEAN,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "value",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: ValidationTypes.OBJECT,
|
|
||||||
params: {
|
|
||||||
allowedKeys: [
|
|
||||||
{
|
|
||||||
name: "paletteColors1",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
strict: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "paletteColors2",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
strict: true,
|
|
||||||
ignoreCase: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const expected = [
|
|
||||||
{
|
|
||||||
isValid: true,
|
|
||||||
parsed: {
|
|
||||||
label: "true",
|
|
||||||
value: "true",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
isValid: true,
|
|
||||||
parsed: { label: true, value: "true" },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
isValid: true,
|
|
||||||
parsed: {
|
|
||||||
paletteColors1: "#ffffff",
|
|
||||||
palettecolors2: "#ffffff",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
inputs.forEach((input, index) => {
|
|
||||||
const result = validate(config[index], input, DUMMY_WIDGET);
|
|
||||||
expect(result).toStrictEqual(expected[index]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("correctly validates objects to fail", () => {
|
|
||||||
const inputs = [
|
|
||||||
{
|
|
||||||
labels: true,
|
|
||||||
values: "true",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
paletteColors1: "#ffffff",
|
|
||||||
palettecolors2: 3,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const config = [
|
|
||||||
{
|
|
||||||
type: ValidationTypes.OBJECT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
allowedKeys: [
|
|
||||||
{
|
|
||||||
name: "label",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "value",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: ValidationTypes.OBJECT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
allowedKeys: [
|
|
||||||
{
|
|
||||||
name: "label",
|
|
||||||
type: ValidationTypes.BOOLEAN,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "value",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: ValidationTypes.OBJECT,
|
|
||||||
params: {
|
|
||||||
allowedKeys: [
|
|
||||||
{
|
|
||||||
name: "paletteColors1",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
strict: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "paletteColors2",
|
|
||||||
type: ValidationTypes.TEXT,
|
|
||||||
params: {
|
|
||||||
strict: true,
|
|
||||||
ignoreCase: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const expected = [
|
|
||||||
{
|
|
||||||
isValid: false,
|
|
||||||
parsed: {
|
|
||||||
labels: true,
|
|
||||||
values: "true",
|
|
||||||
},
|
|
||||||
message: "Missing required key: label Missing required key: value",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
isValid: false,
|
|
||||||
message: "Missing required key: value",
|
|
||||||
parsed: { label: true },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
isValid: false,
|
|
||||||
message:
|
|
||||||
"Value of key: palettecolors2 is invalid: This value does not evaluate to type string",
|
|
||||||
parsed: {
|
|
||||||
paletteColors1: "#ffffff",
|
|
||||||
palettecolors2: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
inputs.forEach((input, index) => {
|
|
||||||
const result = validate(config[index], input, DUMMY_WIDGET);
|
|
||||||
expect(result).toStrictEqual(expected[index]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// describe("Color Picker Text validator", () => {
|
// describe("Color Picker Text validator", () => {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ function validatePlainObject(
|
||||||
if (config.params?.allowedKeys) {
|
if (config.params?.allowedKeys) {
|
||||||
let _valid = true;
|
let _valid = true;
|
||||||
const _messages: string[] = [];
|
const _messages: string[] = [];
|
||||||
const parsedValue: Record<string, unknown> = value;
|
|
||||||
config.params.allowedKeys.forEach((entry) => {
|
config.params.allowedKeys.forEach((entry) => {
|
||||||
const ignoreCase = !!entry.params?.ignoreCase;
|
const ignoreCase = !!entry.params?.ignoreCase;
|
||||||
const entryName = getPropertyEntry(value, entry.name, ignoreCase);
|
const entryName = getPropertyEntry(value, entry.name, ignoreCase);
|
||||||
|
|
@ -65,7 +64,6 @@ function validatePlainObject(
|
||||||
value[entryName],
|
value[entryName],
|
||||||
props,
|
props,
|
||||||
);
|
);
|
||||||
parsedValue[entryName] = parsed;
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
value[entryName] = parsed;
|
value[entryName] = parsed;
|
||||||
_valid = isValid;
|
_valid = isValid;
|
||||||
|
|
@ -80,7 +78,7 @@ function validatePlainObject(
|
||||||
if (_valid) {
|
if (_valid) {
|
||||||
return {
|
return {
|
||||||
isValid: true,
|
isValid: true,
|
||||||
parsed: parsedValue,
|
parsed: value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
|
@ -119,7 +117,7 @@ function validateArray(
|
||||||
config.params?.children?.type === ValidationTypes.OBJECT &&
|
config.params?.children?.type === ValidationTypes.OBJECT &&
|
||||||
(config.params.children.params?.allowedKeys || []).length > 0
|
(config.params.children.params?.allowedKeys || []).length > 0
|
||||||
) {
|
) {
|
||||||
const allowedKeysConfigArray =
|
const allowedKeysCofigArray =
|
||||||
config.params.children.params?.allowedKeys || [];
|
config.params.children.params?.allowedKeys || [];
|
||||||
|
|
||||||
const allowedKeys = (config.params.children.params?.allowedKeys || []).map(
|
const allowedKeys = (config.params.children.params?.allowedKeys || []).map(
|
||||||
|
|
@ -131,7 +129,7 @@ function validateArray(
|
||||||
};
|
};
|
||||||
|
|
||||||
const valueWithType = value as ItemType[];
|
const valueWithType = value as ItemType[];
|
||||||
allowedKeysConfigArray.forEach((allowedKeyConfig) => {
|
allowedKeysCofigArray.forEach((allowedKeyConfig) => {
|
||||||
if (allowedKeyConfig.params?.unique) {
|
if (allowedKeyConfig.params?.unique) {
|
||||||
const allowedKeyValues = valueWithType.map(
|
const allowedKeyValues = valueWithType.map(
|
||||||
(item) => item[allowedKeyConfig.name],
|
(item) => item[allowedKeyConfig.name],
|
||||||
|
|
@ -354,6 +352,7 @@ export const VALIDATORS: Record<ValidationTypes, Validator> = {
|
||||||
isValid: false,
|
isValid: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isValid: true,
|
isValid: true,
|
||||||
parsed,
|
parsed,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user