hunk.code_window:           "sectionName": null,
             "children": [
               {
                 "label": "Host Address",
                 "configProperty": "datasourceConfiguration.endpoints[*].host",
                 "controlType": "KEYVALUE_ARRAY"
               },
               {
                 "label": "Port",
                 "configProperty": "datasourceConfiguration.endpoints[*].port",
                 "dataType": "NUMBER",
  
hunk.labels: keep keep keep keep keep replace keep keep keep keep keep
hunk.after_edit:               "controlType": "KEYVALUE_ARRAY",
                 "validationMessage": "Please enter a valid host",
                 "validationRegex": "^((?![/:]).)*$"
  
hunk.file_path: app/server/appsmith-plugins/postgresPlugin/src/main/resources/form.json
hunk.type: replace
file: import React from "react";
  import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
  import { WidgetType } from "constants/WidgetConstants";
  import { EventType } from "constants/ActionConstants";
  import DropDownComponent from "components/designSystems/blueprint/DropdownComponent";
  import _ from "lodash";
  import {
    WidgetPropertyValidationType,
    BASE_WIDGET_VALIDATION,
  } from "utils/ValidationFactory";
  import { VALIDATION_TYPES } from "constants/WidgetValidation";
  import { TriggerPropertiesMap } from "utils/WidgetFactory";
  import { VALIDATORS } from "utils/Validators";
  import { DataTree } from "entities/DataTree/dataTreeFactory";
  import { Intent as BlueprintIntent } from "@blueprintjs/core";
  import * as Sentry from "@sentry/react";
  
  class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
    static getPropertyValidationMap(): WidgetPropertyValidationType {
      return {
        ...BASE_WIDGET_VALIDATION,
        placeholderText: VALIDATION_TYPES.TEXT,
        label: VALIDATION_TYPES.TEXT,
        options: VALIDATION_TYPES.OPTIONS_DATA,
        selectionType: VALIDATION_TYPES.TEXT,
        isRequired: VALIDATION_TYPES.BOOLEAN,
        // onOptionChange: VALIDATION_TYPES.ACTION_SELECTOR,
        selectedOptionValueArr: VALIDATION_TYPES.ARRAY,
        defaultOptionValue: (
          value: string | string[],
          props: WidgetProps,
          dataTree?: DataTree,
        ) => {
          let values = value;
  
          if (props) {
            if (props.selectionType === "SINGLE_SELECT") {
              return VALIDATORS[VALIDATION_TYPES.TEXT](value, props, dataTree);
            } else if (props.selectionType === "MULTI_SELECT") {
              if (typeof value === "string") {
                try {
                  values = JSON.parse(value);
                  if (!Array.isArray(values)) {
                    throw new Error();
                  }
                } catch {
                  values = value.length ? value.split(",") : [];
                  if (values.length > 0) {
                    values = values.map(value => value.trim());
                  }
                }
              }
            }
          }
  
          if (Array.isArray(values)) {
            values = _.uniq(values);
          }
  
          return {
            isValid: true,
            parsed: values,
          };
        },
      };
    }
  
    static getDerivedPropertiesMap() {
      return {
        isValid: `{{this.isRequired ? this.selectionType === 'SINGLE_SELECT' ? !!this.selectedOption : !!this.selectedIndexArr && this.selectedIndexArr.length > 0 : true}}`,
        selectedOption: `{{ this.selectionType === 'SINGLE_SELECT' ? _.find(this.options, { value:  this.selectedOptionValue }) : undefined}}`,
        selectedOptionArr: `{{this.selectionType === "MULTI_SELECT" ? this.options.filter(opt => _.includes(this.selectedOptionValueArr, opt.value)) : undefined}}`,
        selectedIndex: `{{ _.findIndex(this.options, { value: this.selectedOption.value } ) }}`,
        selectedIndexArr: `{{ this.selectedOptionValueArr.map(o => _.findIndex(this.options, { value: o })) }}`,
        value: `{{ this.selectionType === 'SINGLE_SELECT' ? this.selectedOptionValue : this.selectedOptionValueArr }}`,
      };
    }
  
    static getTriggerPropertyMap(): TriggerPropertiesMap {
      return {
        onOptionChange: true,
      };
    }
  
    static getDefaultPropertiesMap(): Record<string, string> {
      return {
        selectedOptionValue: "defaultOptionValue",
        selectedOptionValueArr: "defaultOptionValue",
      };
    }
  
    static getMetaPropertiesMap(): Record<string, any> {
      return {
        selectedOptionValue: undefined,
        selectedOptionValueArr: undefined,
      };
    }
  
    getPageView() {
      const options = this.props.options || [];
      const selectedIndex = _.findIndex(this.props.options, {
        value: this.props.selectedOptionValue,
      });
      const computedSelectedIndexArr = Array.isArray(
        this.props.selectedOptionValueArr,
      )
        ? this.props.selectedOptionValueArr
            .map((opt: string) =>
              _.findIndex(this.props.options, {
                value: opt,
              }),
            )
            .filter((i: number) => i > -1)
        : [];
      const { componentWidth, componentHeight } = this.getComponentDimensions();
      return (
        <DropDownComponent
          onOptionSelected={this.onOptionSelected}
          onOptionRemoved={this.onOptionRemoved}
          widgetId={this.props.widgetId}
          placeholder={this.props.placeholderText}
          options={options}
          height={componentHeight}
          width={componentWidth}
          selectionType={this.props.selectionType}
          selectedIndex={selectedIndex > -1 ? selectedIndex : undefined}
          selectedIndexArr={computedSelectedIndexArr}
          label={`${this.props.label}`}
          isLoading={this.props.isLoading}
          disabled={this.props.isDisabled}
        />
      );
    }
  
    onOptionSelected = (selectedOption: DropdownOption) => {
      if (this.props.selectionType === "SINGLE_SELECT") {
        this.updateWidgetMetaProperty(
          "selectedOptionValue",
          selectedOption.value,
        );
      } else if (this.props.selectionType === "MULTI_SELECT") {
        const isAlreadySelected = this.props.selectedOptionValueArr.includes(
          selectedOption.value,
        );
  
        let newSelectedValue = [...this.props.selectedOptionValueArr];
        if (isAlreadySelected) {
          newSelectedValue = newSelectedValue.filter(
            v => v !== selectedOption.value,
          );
        } else {
          newSelectedValue.push(selectedOption.value);
        }
        this.updateWidgetMetaProperty("selectedOptionValueArr", newSelectedValue);
      }
      if (this.props.onOptionChange) {
        super.executeAction({
          dynamicString: this.props.onOptionChange,
          event: {
            type: EventType.ON_OPTION_CHANGE,
          },
        });
      }
    };
  
    onOptionRemoved = (removedIndex: number) => {
      const newSelectedValue = this.props.selectedOptionValueArr.filter(
        (v: string) =>
          _.findIndex(this.props.options, { value: v }) !== removedIndex,
      );
      this.updateWidgetMetaProperty("selectedOptionValueArr", newSelectedValue);
      if (this.props.onOptionChange) {
        super.executeAction({
          dynamicString: this.props.onOptionChange,
          event: {
            type: EventType.ON_OPTION_CHANGE,
          },
        });
      }
    };
  
    getWidgetType(): WidgetType {
      return "DROP_DOWN_WIDGET";
    }
  }
  
  export type SelectionType = "SINGLE_SELECT" | "MULTI_SELECT";
  export interface DropdownOption {
    label: string;
    value: string;
    id?: string;
    onSelect?: (option: DropdownOption) => void;
    children?: DropdownOption[];
    intent?: BlueprintIntent;
  }
  
  export interface DropdownWidgetProps extends WidgetProps {
    placeholderText?: string;
    label?: string;
    selectedIndex?: number;
    selectedIndexArr?: number[];
    selectionType: SelectionType;
    selectedOption: DropdownOption;
    options?: DropdownOption[];
    onOptionChange?: string;
    defaultOptionValue?: string | string[];
    isRequired: boolean;
  }
  
  export default DropdownWidget;
  export const ProfiledDropDownWidget = Sentry.withProfiler(DropdownWidget);
  