2020-04-28 06:52:53 +00:00
|
|
|
import React from "react";
|
|
|
|
|
import BaseControl, { ControlProps } from "./BaseControl";
|
|
|
|
|
import styled from "styled-components";
|
2021-12-27 12:04:45 +00:00
|
|
|
import Dropdown, { DropdownOption } from "components/ads/Dropdown";
|
2020-04-28 06:52:53 +00:00
|
|
|
import { ControlType } from "constants/PropertyControlConstants";
|
2021-12-27 12:04:45 +00:00
|
|
|
import _ from "lodash";
|
|
|
|
|
import {
|
|
|
|
|
Field,
|
|
|
|
|
WrappedFieldInputProps,
|
|
|
|
|
WrappedFieldMetaProps,
|
|
|
|
|
} from "redux-form";
|
2022-02-26 17:11:38 +00:00
|
|
|
import { connect } from "react-redux";
|
|
|
|
|
import { AppState } from "reducers";
|
|
|
|
|
import { getDynamicFetchedValues } from "selectors/formSelectors";
|
2020-04-28 06:52:53 +00:00
|
|
|
|
|
|
|
|
const DropdownSelect = styled.div`
|
|
|
|
|
font-size: 14px;
|
2022-01-14 13:50:54 +00:00
|
|
|
width: 20vw;
|
2020-04-28 06:52:53 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
class DropDownControl extends BaseControl<DropDownControlProps> {
|
|
|
|
|
render() {
|
2022-01-14 13:50:54 +00:00
|
|
|
let width = "20vw";
|
|
|
|
|
if (
|
|
|
|
|
"customStyles" in this.props &&
|
|
|
|
|
!!this.props.customStyles &&
|
|
|
|
|
"width" in this.props.customStyles
|
|
|
|
|
) {
|
|
|
|
|
width = this.props.customStyles.width;
|
2021-11-10 13:45:47 +00:00
|
|
|
}
|
2020-04-28 06:52:53 +00:00
|
|
|
|
|
|
|
|
return (
|
2021-12-27 12:04:45 +00:00
|
|
|
<DropdownSelect data-cy={this.props.configProperty} style={{ width }}>
|
|
|
|
|
<Field
|
|
|
|
|
component={renderDropdown}
|
|
|
|
|
name={this.props.configProperty}
|
2022-02-26 17:11:38 +00:00
|
|
|
props={{ ...this.props, width }}
|
2021-12-27 12:04:45 +00:00
|
|
|
type={this.props?.isMultiSelect ? "select-multiple" : undefined}
|
|
|
|
|
/>
|
|
|
|
|
</DropdownSelect>
|
2020-04-28 06:52:53 +00:00
|
|
|
);
|
2021-12-27 12:04:45 +00:00
|
|
|
}
|
2020-04-28 06:52:53 +00:00
|
|
|
|
|
|
|
|
getControlType(): ControlType {
|
|
|
|
|
return "DROP_DOWN";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-26 17:11:38 +00:00
|
|
|
function renderDropdown(
|
|
|
|
|
props: {
|
|
|
|
|
input?: WrappedFieldInputProps;
|
|
|
|
|
meta?: Partial<WrappedFieldMetaProps>;
|
|
|
|
|
width: string;
|
|
|
|
|
} & DropDownControlProps,
|
|
|
|
|
): JSX.Element {
|
2022-03-03 15:42:02 +00:00
|
|
|
let selectedValue: string | string[];
|
2021-12-27 12:04:45 +00:00
|
|
|
if (_.isUndefined(props.input?.value)) {
|
2022-03-03 15:42:02 +00:00
|
|
|
if (props.isMultiSelect)
|
|
|
|
|
selectedValue = props?.initialValue ? (props.initialValue as string) : [];
|
|
|
|
|
else
|
|
|
|
|
selectedValue = props?.initialValue
|
|
|
|
|
? (props.initialValue as string[])
|
|
|
|
|
: "";
|
|
|
|
|
} else {
|
|
|
|
|
if (props.isMultiSelect) {
|
|
|
|
|
selectedValue = props.input?.value ? props.input.value : [];
|
|
|
|
|
if (!Array.isArray(selectedValue)) {
|
|
|
|
|
selectedValue = [selectedValue];
|
|
|
|
|
} else {
|
|
|
|
|
selectedValue = [...new Set(selectedValue)];
|
|
|
|
|
}
|
|
|
|
|
} else selectedValue = props.input?.value ? props.input.value : "";
|
2022-02-26 17:11:38 +00:00
|
|
|
}
|
|
|
|
|
let options: DropdownOption[] = [];
|
2022-03-03 15:42:02 +00:00
|
|
|
let selectedOptions: DropdownOption[] = [];
|
2022-02-26 17:11:38 +00:00
|
|
|
if (typeof props.options === "object" && Array.isArray(props.options)) {
|
|
|
|
|
options = props.options;
|
2022-03-03 15:42:02 +00:00
|
|
|
selectedOptions =
|
|
|
|
|
options.filter((option: DropdownOption) => {
|
|
|
|
|
if (props.isMultiSelect)
|
|
|
|
|
return selectedValue.includes(option.value as string);
|
|
|
|
|
else return selectedValue === option.value;
|
|
|
|
|
}) || [];
|
2021-12-27 12:04:45 +00:00
|
|
|
}
|
2022-03-03 15:42:02 +00:00
|
|
|
// Function to handle selction of options
|
|
|
|
|
const onSelectOptions = (value: string | undefined) => {
|
|
|
|
|
if (value) {
|
|
|
|
|
if (props.isMultiSelect) {
|
|
|
|
|
if (Array.isArray(selectedValue)) {
|
|
|
|
|
if (!selectedValue.includes(value))
|
|
|
|
|
(selectedValue as string[]).push(value);
|
|
|
|
|
} else {
|
|
|
|
|
selectedValue = [selectedValue as string, value];
|
|
|
|
|
}
|
|
|
|
|
} else selectedValue = value;
|
|
|
|
|
props.input?.onChange(selectedValue);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Function to handle deselction of options
|
|
|
|
|
const onRemoveOptions = (value: string | undefined) => {
|
|
|
|
|
if (value) {
|
|
|
|
|
if (props.isMultiSelect) {
|
|
|
|
|
if (Array.isArray(selectedValue)) {
|
|
|
|
|
if (selectedValue.includes(value))
|
|
|
|
|
(selectedValue as string[]).splice(
|
|
|
|
|
(selectedValue as string[]).indexOf(value),
|
|
|
|
|
1,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
selectedValue = [];
|
|
|
|
|
}
|
|
|
|
|
} else selectedValue = "";
|
|
|
|
|
props.input?.onChange(selectedValue);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2021-12-27 12:04:45 +00:00
|
|
|
return (
|
|
|
|
|
<Dropdown
|
|
|
|
|
boundary="window"
|
2022-01-06 14:39:21 +00:00
|
|
|
disabled={props.disabled}
|
2021-12-27 12:04:45 +00:00
|
|
|
dontUsePortal={false}
|
|
|
|
|
dropdownMaxHeight="250px"
|
2022-03-03 15:42:02 +00:00
|
|
|
enableSearch={props.isSearchable}
|
2022-01-13 08:07:30 +00:00
|
|
|
isLoading={props.isLoading}
|
2022-02-26 17:11:38 +00:00
|
|
|
isMultiSelect={props?.isMultiSelect}
|
2022-03-03 15:42:02 +00:00
|
|
|
onSelect={onSelectOptions}
|
2022-01-14 13:50:54 +00:00
|
|
|
optionWidth={props.width}
|
2022-02-26 17:11:38 +00:00
|
|
|
options={options}
|
|
|
|
|
placeholder={props?.placeholderText}
|
2022-03-03 15:42:02 +00:00
|
|
|
removeSelectedOption={onRemoveOptions}
|
|
|
|
|
selected={props.isMultiSelect ? selectedOptions : selectedOptions[0]}
|
2021-12-27 12:04:45 +00:00
|
|
|
showLabelOnly
|
2022-01-14 13:50:54 +00:00
|
|
|
width={props.width}
|
2021-12-27 12:04:45 +00:00
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-28 06:52:53 +00:00
|
|
|
export interface DropDownControlProps extends ControlProps {
|
|
|
|
|
options: DropdownOption[];
|
|
|
|
|
placeholderText: string;
|
|
|
|
|
propertyValue: string;
|
2021-02-26 06:58:47 +00:00
|
|
|
subtitle?: string;
|
2021-12-27 12:04:45 +00:00
|
|
|
isMultiSelect?: boolean;
|
2021-11-10 13:45:47 +00:00
|
|
|
isSearchable?: boolean;
|
2022-01-06 10:03:20 +00:00
|
|
|
fetchOptionsCondtionally?: boolean;
|
2022-02-26 17:11:38 +00:00
|
|
|
isLoading: boolean;
|
2020-04-28 06:52:53 +00:00
|
|
|
}
|
2022-01-06 10:03:20 +00:00
|
|
|
|
2022-02-26 17:11:38 +00:00
|
|
|
const mapStateToProps = (
|
|
|
|
|
state: AppState,
|
|
|
|
|
ownProps: DropDownControlProps,
|
|
|
|
|
): { isLoading: boolean; options: DropdownOption[] } => {
|
|
|
|
|
// Added default options to prevent error when options is undefined
|
|
|
|
|
let isLoading = false;
|
|
|
|
|
let options: DropdownOption[] = ownProps.fetchOptionsCondtionally
|
|
|
|
|
? []
|
|
|
|
|
: ownProps.options;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (ownProps.fetchOptionsCondtionally) {
|
|
|
|
|
const dynamicFetchedValues = getDynamicFetchedValues(
|
|
|
|
|
state,
|
|
|
|
|
ownProps.configProperty,
|
|
|
|
|
);
|
|
|
|
|
isLoading = dynamicFetchedValues.isLoading;
|
|
|
|
|
options = dynamicFetchedValues.data;
|
|
|
|
|
}
|
|
|
|
|
return { isLoading, options };
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return {
|
|
|
|
|
isLoading,
|
|
|
|
|
options,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Connecting this componenet to the state to allow for dynamic fetching of options to be updated.
|
|
|
|
|
export default connect(mapStateToProps)(DropDownControl);
|