2022-02-02 14:15:07 +00:00
|
|
|
import React from "react";
|
|
|
|
|
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
|
|
|
|
import { WidgetType } from "constants/WidgetConstants";
|
|
|
|
|
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
2022-02-22 08:43:35 +00:00
|
|
|
import { isArray, isString, isNumber } from "lodash";
|
|
|
|
|
import {
|
|
|
|
|
ValidationResponse,
|
|
|
|
|
ValidationTypes,
|
|
|
|
|
} from "constants/WidgetValidation";
|
2022-02-02 14:15:07 +00:00
|
|
|
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
|
|
|
|
import MultiSelectComponent from "../component";
|
|
|
|
|
import {
|
|
|
|
|
DefaultValueType,
|
|
|
|
|
LabelValueType,
|
|
|
|
|
} from "rc-select/lib/interface/generator";
|
|
|
|
|
import { Layers } from "constants/Layers";
|
|
|
|
|
import { MinimumPopupRows, GRID_DENSITY_MIGRATION_V1 } from "widgets/constants";
|
2022-02-22 08:43:35 +00:00
|
|
|
import { AutocompleteDataType } from "utils/autocomplete/TernServer";
|
|
|
|
|
|
|
|
|
|
export function defaultOptionValueValidation(
|
|
|
|
|
value: unknown,
|
|
|
|
|
props: MultiSelectWidgetProps,
|
|
|
|
|
_: any,
|
|
|
|
|
): ValidationResponse {
|
|
|
|
|
let isValid;
|
|
|
|
|
let parsed;
|
|
|
|
|
let message = "";
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Function to check if the object has `label` and `value`
|
|
|
|
|
*/
|
|
|
|
|
const hasLabelValue = (obj: any) => {
|
|
|
|
|
return (
|
|
|
|
|
_.isPlainObject(obj) &&
|
|
|
|
|
obj.hasOwnProperty("label") &&
|
|
|
|
|
obj.hasOwnProperty("value") &&
|
|
|
|
|
_.isString(obj.label) &&
|
|
|
|
|
(_.isString(obj.value) || _.isFinite(obj.value))
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Function to check for duplicate values in array
|
|
|
|
|
*/
|
|
|
|
|
const hasUniqueValues = (arr: Array<string>) => {
|
|
|
|
|
const uniqueValues = new Set(arr);
|
|
|
|
|
|
|
|
|
|
return uniqueValues.size === arr.length;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* When value is "['green', 'red']", "[{label: 'green', value: 'green'}]" and "green, red"
|
|
|
|
|
*/
|
|
|
|
|
if (_.isString(value) && (value as string).trim() !== "") {
|
|
|
|
|
try {
|
|
|
|
|
/*
|
|
|
|
|
* when value is "['green', 'red']", "[{label: 'green', value: 'green'}]"
|
|
|
|
|
*/
|
|
|
|
|
value = JSON.parse(value as string);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
/*
|
|
|
|
|
* when value is "green, red", JSON.parse throws error
|
|
|
|
|
*/
|
|
|
|
|
const splitByComma = (value as string).split(",") || [];
|
|
|
|
|
|
|
|
|
|
value = splitByComma.map((s) => s.trim());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_.isString(value) && (value as string).trim() === "") {
|
|
|
|
|
isValid = true;
|
|
|
|
|
parsed = [];
|
|
|
|
|
message = "";
|
|
|
|
|
} else if (Array.isArray(value)) {
|
|
|
|
|
if (value.every((val) => _.isString(val) || _.isFinite(val))) {
|
|
|
|
|
/*
|
|
|
|
|
* When value is ["green", "red"]
|
|
|
|
|
*/
|
|
|
|
|
if (hasUniqueValues(value as [])) {
|
|
|
|
|
isValid = true;
|
|
|
|
|
parsed = value;
|
|
|
|
|
message = "";
|
|
|
|
|
} else {
|
|
|
|
|
isValid = false;
|
|
|
|
|
parsed = [];
|
|
|
|
|
message = "values must be unique. Duplicate values found";
|
|
|
|
|
}
|
|
|
|
|
} else if (value.every(hasLabelValue)) {
|
|
|
|
|
/*
|
|
|
|
|
* When value is [{label: "green", value: "red"}]
|
|
|
|
|
*/
|
|
|
|
|
if (hasUniqueValues(value.map((val) => val.value) as [])) {
|
|
|
|
|
isValid = true;
|
|
|
|
|
parsed = value;
|
|
|
|
|
message = "";
|
|
|
|
|
} else {
|
|
|
|
|
isValid = false;
|
|
|
|
|
parsed = [];
|
|
|
|
|
message = "path:value must be unique. Duplicate values found";
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* When value is [true, false], [undefined, undefined] etc.
|
|
|
|
|
*/
|
|
|
|
|
isValid = false;
|
|
|
|
|
parsed = [];
|
|
|
|
|
message =
|
|
|
|
|
"value should match: Array<string | number> | Array<{label: string, value: string | number}>";
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* When value is undefined, null, {} etc.
|
|
|
|
|
*/
|
|
|
|
|
isValid = false;
|
|
|
|
|
parsed = [];
|
|
|
|
|
message =
|
|
|
|
|
"value should match: Array<string | number> | Array<{label: string, value: string | number}>";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
isValid,
|
|
|
|
|
parsed,
|
|
|
|
|
messages: [message],
|
|
|
|
|
};
|
|
|
|
|
}
|
2022-02-02 14:15:07 +00:00
|
|
|
|
|
|
|
|
class MultiSelectWidget extends BaseWidget<
|
|
|
|
|
MultiSelectWidgetProps,
|
|
|
|
|
WidgetState
|
|
|
|
|
> {
|
|
|
|
|
static getPropertyPaneConfig() {
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
sectionName: "General",
|
|
|
|
|
children: [
|
|
|
|
|
{
|
|
|
|
|
helpText:
|
|
|
|
|
"Allows users to select multiple options. Values must be unique",
|
|
|
|
|
propertyName: "options",
|
|
|
|
|
label: "Options",
|
|
|
|
|
controlType: "INPUT_TEXT",
|
|
|
|
|
placeholderText: '[{ "label": "Option1", "value": "Option2" }]',
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
isJSConvertible: false,
|
|
|
|
|
validation: {
|
|
|
|
|
type: ValidationTypes.ARRAY,
|
|
|
|
|
params: {
|
|
|
|
|
unique: ["value"],
|
|
|
|
|
children: {
|
|
|
|
|
type: ValidationTypes.OBJECT,
|
|
|
|
|
params: {
|
|
|
|
|
required: true,
|
|
|
|
|
allowedKeys: [
|
|
|
|
|
{
|
|
|
|
|
name: "label",
|
|
|
|
|
type: ValidationTypes.TEXT,
|
|
|
|
|
params: {
|
|
|
|
|
default: "",
|
|
|
|
|
requiredKey: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "value",
|
|
|
|
|
type: ValidationTypes.TEXT,
|
|
|
|
|
params: {
|
|
|
|
|
default: "",
|
|
|
|
|
requiredKey: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
evaluationSubstitutionType:
|
|
|
|
|
EvaluationSubstitutionType.SMART_SUBSTITUTE,
|
|
|
|
|
},
|
|
|
|
|
{
|
2022-02-22 08:43:35 +00:00
|
|
|
helpText: "Selects the option(s) with value by default",
|
2022-02-02 14:15:07 +00:00
|
|
|
propertyName: "defaultOptionValue",
|
|
|
|
|
label: "Default Value",
|
|
|
|
|
controlType: "INPUT_TEXT",
|
|
|
|
|
placeholderText: "[GREEN]",
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: {
|
2022-02-22 08:43:35 +00:00
|
|
|
type: ValidationTypes.FUNCTION,
|
2022-02-02 14:15:07 +00:00
|
|
|
params: {
|
2022-02-22 08:43:35 +00:00
|
|
|
fn: defaultOptionValueValidation,
|
|
|
|
|
expected: {
|
|
|
|
|
type: "Array of values",
|
|
|
|
|
example: `['option1', 'option2'] | [{ "label": "label1", "value": "value1" }]`,
|
|
|
|
|
autocompleteDataType: AutocompleteDataType.ARRAY,
|
2022-02-02 14:15:07 +00:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
evaluationSubstitutionType:
|
|
|
|
|
EvaluationSubstitutionType.SMART_SUBSTITUTE,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
helpText: "Sets a Label Text",
|
|
|
|
|
propertyName: "labelText",
|
|
|
|
|
label: "Label Text",
|
|
|
|
|
controlType: "INPUT_TEXT",
|
|
|
|
|
placeholderText: "Enter Label text",
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.TEXT },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
helpText: "Sets a Placeholder Text",
|
|
|
|
|
propertyName: "placeholderText",
|
|
|
|
|
label: "Placeholder",
|
|
|
|
|
controlType: "INPUT_TEXT",
|
|
|
|
|
placeholderText: "Search",
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.TEXT },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
propertyName: "isRequired",
|
|
|
|
|
label: "Required",
|
|
|
|
|
helpText: "Makes input to the widget mandatory",
|
|
|
|
|
controlType: "SWITCH",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.BOOLEAN },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
helpText: "Controls the visibility of the widget",
|
|
|
|
|
propertyName: "isVisible",
|
|
|
|
|
label: "Visible",
|
|
|
|
|
controlType: "SWITCH",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.BOOLEAN },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
propertyName: "isDisabled",
|
|
|
|
|
label: "Disabled",
|
|
|
|
|
helpText: "Disables input to this widget",
|
|
|
|
|
controlType: "SWITCH",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.BOOLEAN },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
propertyName: "animateLoading",
|
|
|
|
|
label: "Animate Loading",
|
|
|
|
|
controlType: "SWITCH",
|
|
|
|
|
helpText: "Controls the loading of the widget",
|
|
|
|
|
defaultValue: true,
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.BOOLEAN },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
propertyName: "isFilterable",
|
|
|
|
|
label: "Filterable",
|
|
|
|
|
helpText: "Makes the dropdown list filterable",
|
|
|
|
|
controlType: "SWITCH",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.BOOLEAN },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
helpText: "Enables server side filtering of the data",
|
|
|
|
|
propertyName: "serverSideFiltering",
|
|
|
|
|
label: "Server Side Filtering",
|
|
|
|
|
controlType: "SWITCH",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.BOOLEAN },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
helpText:
|
|
|
|
|
"Controls the visibility of select all option in dropdown.",
|
|
|
|
|
propertyName: "allowSelectAll",
|
|
|
|
|
label: "Allow Select All",
|
|
|
|
|
controlType: "SWITCH",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.BOOLEAN },
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
sectionName: "Styles",
|
|
|
|
|
children: [
|
|
|
|
|
{
|
|
|
|
|
propertyName: "labelTextColor",
|
|
|
|
|
label: "Label Text Color",
|
|
|
|
|
controlType: "COLOR_PICKER",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.TEXT },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
propertyName: "labelTextSize",
|
|
|
|
|
label: "Label Text Size",
|
|
|
|
|
controlType: "DROP_DOWN",
|
|
|
|
|
defaultValue: "PARAGRAPH",
|
|
|
|
|
options: [
|
|
|
|
|
{
|
|
|
|
|
label: "Heading 1",
|
|
|
|
|
value: "HEADING1",
|
|
|
|
|
subText: "24px",
|
|
|
|
|
icon: "HEADING_ONE",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: "Heading 2",
|
|
|
|
|
value: "HEADING2",
|
|
|
|
|
subText: "18px",
|
|
|
|
|
icon: "HEADING_TWO",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: "Heading 3",
|
|
|
|
|
value: "HEADING3",
|
|
|
|
|
subText: "16px",
|
|
|
|
|
icon: "HEADING_THREE",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: "Paragraph",
|
|
|
|
|
value: "PARAGRAPH",
|
|
|
|
|
subText: "14px",
|
|
|
|
|
icon: "PARAGRAPH",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: "Paragraph 2",
|
|
|
|
|
value: "PARAGRAPH2",
|
|
|
|
|
subText: "12px",
|
|
|
|
|
icon: "PARAGRAPH_TWO",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
isBindProperty: false,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
propertyName: "labelStyle",
|
|
|
|
|
label: "Label Font Style",
|
|
|
|
|
controlType: "BUTTON_TABS",
|
|
|
|
|
options: [
|
|
|
|
|
{
|
|
|
|
|
icon: "BOLD_FONT",
|
|
|
|
|
value: "BOLD",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
icon: "ITALICS_FONT",
|
|
|
|
|
value: "ITALIC",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: false,
|
|
|
|
|
validation: { type: ValidationTypes.TEXT },
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
sectionName: "Actions",
|
|
|
|
|
children: [
|
|
|
|
|
{
|
|
|
|
|
helpText: "Triggers an action when a user selects an option",
|
|
|
|
|
propertyName: "onOptionChange",
|
|
|
|
|
label: "onOptionChange",
|
|
|
|
|
controlType: "ACTION_SELECTOR",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
helpText: "Trigger an action on change of filterText",
|
|
|
|
|
hidden: (props: MultiSelectWidgetProps) =>
|
|
|
|
|
!props.serverSideFiltering,
|
|
|
|
|
dependencies: ["serverSideFiltering"],
|
|
|
|
|
propertyName: "onFilterUpdate",
|
|
|
|
|
label: "onFilterUpdate",
|
|
|
|
|
controlType: "ACTION_SELECTOR",
|
|
|
|
|
isJSConvertible: true,
|
|
|
|
|
isBindProperty: true,
|
|
|
|
|
isTriggerProperty: true,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static getDerivedPropertiesMap() {
|
|
|
|
|
return {
|
2022-02-22 08:43:35 +00:00
|
|
|
selectedOptionLabels: `{{ this.selectedOptions ? this.selectedOptions.map((o) => _.isNil(o.label) ? o : o.label ) : [] }}`,
|
|
|
|
|
selectedOptionValues: `{{ this.selectedOptions ? this.selectedOptions.map((o) => _.isNil(o.value) ? o : o.value ) : [] }}`,
|
2022-02-02 14:15:07 +00:00
|
|
|
isValid: `{{this.isRequired ? !!this.selectedOptionValues && this.selectedOptionValues.length > 0 : true}}`,
|
feat: Internal property to detect changes in a form
-- Implement dirty check logic for a form
-- Expose an form property, hasChanges for checking if the user has changed any values in the form
-- Add isDirty derived property for the following widgets: AudioRecorderWidget, CameraWidget, CheckboxGroupWidget, CheckboxWidget, CurrencyInputWidget, DatePickerWidget2, FilePickerWidgetV2, InputWidgetV2, MultiSelectTreeWidget, MultiSelectWidgetV2, PhoneInputWidget, RadioGroupWidget, RichTextEditorWidget, SelectWidget, SingleSelectTreeWidget, SwitchGroupWidget, SwitchWidget
2022-02-23 08:03:51 +00:00
|
|
|
isDirty: `{{ ((array1, array2) => {if (array1.length === array2.length) {return !array1.map((o) => o.value).every(element => array2.includes(element));} return true;})(this.defaultOptionValue, this.selectedOptionValues); }}`,
|
2022-02-02 14:15:07 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static getDefaultPropertiesMap(): Record<string, string> {
|
|
|
|
|
return {
|
|
|
|
|
selectedOptions: "defaultOptionValue",
|
|
|
|
|
filterText: "",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static getMetaPropertiesMap(): Record<string, any> {
|
|
|
|
|
return {
|
|
|
|
|
selectedOptions: undefined,
|
|
|
|
|
filterText: "",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getPageView() {
|
|
|
|
|
const options = isArray(this.props.options) ? this.props.options : [];
|
|
|
|
|
const dropDownWidth = MinimumPopupRows * this.props.parentColumnSpace;
|
|
|
|
|
const { componentWidth } = this.getComponentDimensions();
|
2022-02-22 08:43:35 +00:00
|
|
|
const values: LabelValueType[] = this.props.selectedOptions
|
|
|
|
|
? this.props.selectedOptions.map((o) =>
|
|
|
|
|
isString(o) || isNumber(o)
|
|
|
|
|
? { label: o, value: o }
|
|
|
|
|
: { label: o.label, value: o.value },
|
|
|
|
|
)
|
|
|
|
|
: [];
|
2022-02-02 14:15:07 +00:00
|
|
|
return (
|
|
|
|
|
<MultiSelectComponent
|
|
|
|
|
allowSelectAll={this.props.allowSelectAll}
|
|
|
|
|
compactMode={
|
|
|
|
|
!(
|
|
|
|
|
(this.props.bottomRow - this.props.topRow) /
|
|
|
|
|
GRID_DENSITY_MIGRATION_V1 >
|
|
|
|
|
1
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
disabled={this.props.isDisabled ?? false}
|
|
|
|
|
dropDownWidth={dropDownWidth}
|
|
|
|
|
dropdownStyle={{
|
|
|
|
|
zIndex: Layers.dropdownModalWidget,
|
|
|
|
|
}}
|
|
|
|
|
filterText={this.props.filterText}
|
|
|
|
|
isFilterable={this.props.isFilterable}
|
|
|
|
|
isValid={this.props.isValid}
|
|
|
|
|
labelStyle={this.props.labelStyle}
|
|
|
|
|
labelText={this.props.labelText}
|
|
|
|
|
labelTextColor={this.props.labelTextColor}
|
|
|
|
|
labelTextSize={this.props.labelTextSize}
|
|
|
|
|
loading={this.props.isLoading}
|
|
|
|
|
onChange={this.onOptionChange}
|
|
|
|
|
onFilterChange={this.onFilterChange}
|
|
|
|
|
options={options}
|
|
|
|
|
placeholder={this.props.placeholderText as string}
|
|
|
|
|
serverSideFiltering={this.props.serverSideFiltering}
|
2022-02-22 08:43:35 +00:00
|
|
|
value={values}
|
2022-02-02 14:15:07 +00:00
|
|
|
widgetId={this.props.widgetId}
|
|
|
|
|
width={componentWidth}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onOptionChange = (value: DefaultValueType) => {
|
2022-02-22 08:43:35 +00:00
|
|
|
if (!this.props.isDirty) {
|
|
|
|
|
this.props.updateWidgetMetaProperty("isDirty", true);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 14:15:07 +00:00
|
|
|
this.props.updateWidgetMetaProperty("selectedOptions", value, {
|
|
|
|
|
triggerPropertyName: "onOptionChange",
|
|
|
|
|
dynamicString: this.props.onOptionChange,
|
|
|
|
|
event: {
|
|
|
|
|
type: EventType.ON_OPTION_CHANGE,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onFilterChange = (value: string) => {
|
|
|
|
|
this.props.updateWidgetMetaProperty("filterText", value);
|
|
|
|
|
|
|
|
|
|
if (this.props.onFilterUpdate && this.props.serverSideFiltering) {
|
|
|
|
|
super.executeAction({
|
|
|
|
|
triggerPropertyName: "onFilterUpdate",
|
|
|
|
|
dynamicString: this.props.onFilterUpdate,
|
|
|
|
|
event: {
|
|
|
|
|
type: EventType.ON_FILTER_UPDATE,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static getWidgetType(): WidgetType {
|
|
|
|
|
return "MULTI_SELECT_WIDGET_V2";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface DropdownOption {
|
|
|
|
|
label: string;
|
|
|
|
|
value: string;
|
|
|
|
|
disabled?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MultiSelectWidgetProps extends WidgetProps {
|
|
|
|
|
placeholderText?: string;
|
|
|
|
|
selectedIndex?: number;
|
|
|
|
|
selectedIndexArr?: number[];
|
|
|
|
|
selectedOption: DropdownOption;
|
|
|
|
|
options?: DropdownOption[];
|
|
|
|
|
onOptionChange: string;
|
|
|
|
|
onFilterChange: string;
|
|
|
|
|
defaultOptionValue: string | string[];
|
|
|
|
|
isRequired: boolean;
|
|
|
|
|
isLoading: boolean;
|
|
|
|
|
selectedOptions: LabelValueType[];
|
|
|
|
|
filterText: string;
|
|
|
|
|
selectedOptionValues: string[];
|
|
|
|
|
selectedOptionLabels: string[];
|
|
|
|
|
serverSideFiltering: boolean;
|
|
|
|
|
onFilterUpdate: string;
|
|
|
|
|
allowSelectAll?: boolean;
|
|
|
|
|
isFilterable: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default MultiSelectWidget;
|