change(ui) - search optimization and autocomplete improvements

This commit is contained in:
Shekar Siri 2022-06-30 15:23:25 +02:00
parent de8eefdffc
commit e3ead3ebb1
5 changed files with 464 additions and 472 deletions

View file

@ -1,81 +1,61 @@
.wrapper {
border: solid thin $gray-light !important;
border-radius: 3px;
border-radius: 3px;
display: flex;
align-items: center;
background-color: white;
width: 100%;
& input {
height: 24px;
font-size: 13px !important;
padding: 0 5px !important;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
border: solid thin transparent !important;
width: 100%;
}
& .right {
height: 24px;
border: solid thin $gray-light !important;
border-radius: 3px;
background-color: white !important;
display: flex;
align-items: stretch;
padding: 0;
background-color: $gray-lightest;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
align-items: center;
height: 26px;
width: 100%;
& div {
/* background-color: red; */
border-left: solid thin $gray-light !important;
width: 28px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
&:last-child {
& .right {
height: 24px;
display: flex;
align-items: stretch;
padding: 0;
background-color: $gray-lightest;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
&:hover {
background-color: $gray-light;
}
margin-left: auto;
& div {
/* background-color: red; */
border-left: solid thin $gray-light !important;
width: 28px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
&:last-child {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
&:hover {
background-color: $gray-light;
}
}
}
}
}
.menu {
border-radius: 0 0 3px 3px;
border: solid thin $gray-light !important;
box-shadow: 0 2px 2px 0 $gray-light;
min-height: 50px;
background-color: white;
max-height: 350px;
overflow-y: auto;
position: absolute;
top: 28px;
left: 0;
width: 400px;
z-index: 99;
.operatorDropdown {
font-weight: 400;
/* height: 30px; */
min-width: 60px;
display: flex !important;
align-items: center;
justify-content: space-between;
padding: 0 8px !important;
font-size: 13px;
height: 26px;
/* background-color: rgba(255, 255, 255, 0.8) !important; */
/* background-color: $gray-lightest !important; */
/* border: solid thin rgba(34, 36, 38, 0.15) !important; */
/* border-radius: 4px !important; */
color: $gray-darkest !important;
font-size: 14px !important;
&.ui.basic.button {
box-shadow: 0 0 0 1px rgba(62, 170, 175, 36, 38, 0.35) inset, 0 0 0 0 rgba(62, 170, 175, 0.15) inset !important;
}
/*
& input {
padding: 0 8px !important;
} */
}
.filterItem {
display: flex;
align-items: center;
padding: 8px 10px;
cursor: pointer;
border-radius: 3px;
/* transition: all 0.4s; */
margin-bottom: 5px;
max-width: 100%;
& .label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&:hover {
background-color: $gray-lightest;
/* transition: all 0.2s; */
}
}

View file

@ -1,155 +1,178 @@
import React, { useState, useEffect } from 'react';
import { Icon, Loader } from 'UI';
import { Icon } from 'UI';
import APIClient from 'App/api_client';
import { debounce } from 'App/utils';
import stl from './FilterAutoComplete.module.css';
import cn from 'classnames';
import { components, DropdownIndicatorProps } from 'react-select';
import AsyncCreatableSelect from 'react-select/async-creatable';
const hiddenStyle = {
whiteSpace: 'pre-wrap',
opacity: 0, position: 'fixed', left: '-3000px'
const dropdownStyles = {
control: (provided: any) => {
const obj = {
...provided,
border: 'solid thin transparent !important',
backgroundColor: 'transparent',
cursor: 'pointer',
height: '26px',
minHeight: '26px',
borderRadius: '3px',
boxShadow: 'none !important',
};
return obj;
},
valueContainer: (provided: any) => ({
...provided,
// paddingRight: '0px',
width: 'fit-content',
alignItems: 'center',
height: '26px',
padding: '0 3px',
}),
// placeholder: (provided: any) => ({
// ...provided,
// }),
indicatorsContainer: (provided: any) => ({
...provided,
padding: '0px',
height: '26px',
}),
option: (provided: any, state: any) => ({
...provided,
whiteSpace: 'nowrap',
}),
menu: (provided: any, state: any) => ({
...provided,
top: 20,
left: 0,
minWidth: 'fit-content',
overflow: 'hidden',
}),
container: (provided: any) => ({
...provided,
width: '100%',
}),
input: (provided: any) => ({
...provided,
height: '22px',
'& input:focus': {
border: 'none !important',
},
}),
singleValue: (provided: any, state: { isDisabled: any }) => {
const opacity = state.isDisabled ? 0.5 : 1;
const transition = 'opacity 300ms';
return {
...provided,
opacity,
transition,
display: 'flex',
alignItems: 'center',
height: '20px',
};
},
};
interface Props {
showOrButton?: boolean;
showCloseButton?: boolean;
onRemoveValue?: () => void;
onAddValue?: () => void;
endpoint?: string;
method?: string;
params?: any;
headerText?: string;
placeholder?: string;
onSelect: (e: any, item: any) => void;
value: any;
icon?: string;
showOrButton?: boolean;
showCloseButton?: boolean;
onRemoveValue?: () => void;
onAddValue?: () => void;
endpoint?: string;
method?: string;
params?: any;
headerText?: string;
placeholder?: string;
onSelect: (e: any, item: any) => void;
value: any;
icon?: string;
}
function FilterAutoComplete(props: Props) {
const {
showCloseButton = false,
placeholder = 'Type to search',
method = 'GET',
showOrButton = false,
onRemoveValue = () => null,
onAddValue = () => null,
endpoint = '',
params = {},
headerText = '',
value = '',
icon = null,
} = props;
const [showModal, setShowModal] = useState(false);
const [loading, setLoading] = useState(false)
const [options, setOptions] = useState<any>([]);
const [query, setQuery] = useState(value);
const {
showCloseButton = false,
placeholder = 'Type to search',
method = 'GET',
showOrButton = false,
onRemoveValue = () => null,
onAddValue = () => null,
endpoint = '',
params = {},
value = '',
} = props;
const [options, setOptions] = useState<any>(value ? [{ label: value, value }] : []);
const [query, setQuery] = useState(value);
const requestValues = (q: any) => {
setLoading(true);
useEffect(() => {
setQuery(value);
}, [value, options])
return new APIClient()[method?.toLocaleLowerCase()](endpoint, { ...params, q })
.then((response: any) => {
if (response.ok) {
return response.json();
}
throw new Error(response.statusText);
})
.then(({ data }: any) => {
setOptions(data);
})
.finally(() => setLoading(false));
}
const debouncedRequestValues = React.useCallback(debounce(requestValues, 1000), [params]);
const onInputChange = ({ target: { value } }: any) => {
setQuery(value);
if (!showModal) {
setShowModal(true);
}
if (value === '' || value === ' ') {
return
}
debouncedRequestValues(value);
}
useEffect(() => {
setQuery(value);
}, [value])
const onBlur = (e) => {
setTimeout(() => { setShowModal(false) }, 200)
if (query !== value) {
props.onSelect(e, { value: query })
}
}
const onItemClick = (e: any, item: any) => {
e.stopPropagation();
e.preventDefault();
if (query !== item.value) {
setQuery(item.value);
}
props.onSelect(e, item);
}
return (
<div className="relative flex items-center">
<div className={stl.wrapper}>
<input
name="query"
onChange={ onInputChange }
onBlur={ onBlur }
value={ query }
autoFocus={ true }
type="text"
placeholder={ placeholder }
autoComplete="do-not-autofill-bad-chrome"
// onPaste={(e) => {
// const text = e.clipboardData.getData('Text');
// // this.hiddenInput.value = text;
// // pasted = true; // to use only the hidden input
// } }
/>
<div
className={stl.right}
>
{ showCloseButton && <div onClick={onRemoveValue}><Icon name="close" size="12" /></div> }
{ showOrButton && <div onClick={onAddValue} className="color-teal"><span className="px-1">or</span></div> }
</div>
</div>
{ !showOrButton && <div className="ml-3">or</div> }
{ showModal && (
<div className={ stl.menu }>
<Loader loading={loading} size="small">
{ options.length === 0 ? (
<div className="p-4 w-full">No results found!</div>
) : (
<div>
{
options.map((item: any, i: any) => (
<div
key={item.value + '_' + i}
className={ cn(stl.filterItem) }
id="filter-item" onClick={ (e) => onItemClick(e, item) }
>
{ icon && <Icon name={ icon } size="16" marginRight="8" /> }
<span className={ stl.label }>{ item.value }</span>
</div>
))
const loadOptions = (inputValue: string, callback: (options: []) => void) => {
new APIClient()
[method?.toLocaleLowerCase()](endpoint, { ...params, q: inputValue })
.then((response: any) => {
if (response.ok) {
return response.json();
}
</div>
)}
</Loader>
throw new Error(response.statusText);
})
.then(({ data }: any) => {
const _options = data.map((i: any) => ({ value: i.value, label: i.value })) || [];
setOptions(_options);
callback(_options);
})
};
const debouncedLoadOptions = React.useCallback(debounce(loadOptions, 1000), [params]);
const handleInputChange = (newValue: string) => {
const inputValue = newValue.replace(/\W/g, '');
setQuery(inputValue);
return inputValue;
};
return (
<div className="relative flex items-center">
<div className={stl.wrapper}>
<AsyncCreatableSelect
cacheOptions
defaultOptions={options}
loadOptions={debouncedLoadOptions}
onInputChange={handleInputChange}
onChange={(obj: any) => props.onSelect(null, obj)}
styles={dropdownStyles}
placeholder={placeholder}
value={value ? options.find((i: any) => i.value === query) : null}
components={{
IndicatorSeparator: () => null,
DropdownIndicator,
}}
/>
<div className={stl.right}>
{showCloseButton && (
<div onClick={props.onRemoveValue}>
<Icon name="close" size="12" />
</div>
)}
{showOrButton && (
<div onClick={props.onAddValue} className="color-teal">
<span className="px-1">or</span>
</div>
)}
</div>
</div>
{!showOrButton && <div className="ml-3">or</div>}
</div>
)}
</div>
);
);
}
export default FilterAutoComplete;
const DropdownIndicator = (props: DropdownIndicatorProps<true>) => {
return (
<components.DropdownIndicator {...props}>
<Icon name="chevron-down" size="16" />
</components.DropdownIndicator>
);
};

View file

@ -8,107 +8,107 @@ import { FilterKey, FilterType } from 'App/types/filter/filterType';
import SubFilterItem from '../SubFilterItem';
interface Props {
filterIndex: number;
filter: any; // event/filter
onUpdate: (filter) => void;
onRemoveFilter: () => void;
isFilter?: boolean;
saveRequestPayloads?: boolean;
filterIndex: number;
filter: any; // event/filter
onUpdate: (filter) => void;
onRemoveFilter: () => void;
isFilter?: boolean;
saveRequestPayloads?: boolean;
}
function FilterItem(props: Props) {
const { isFilter = false, filterIndex, filter, saveRequestPayloads } = props;
const canShowValues = !(filter.operator === "isAny" || filter.operator === "onAny" || filter.operator === "isUndefined");
const isSubFilter = filter.type === FilterType.SUB_FILTERS;
const { isFilter = false, filterIndex, filter, saveRequestPayloads } = props;
const canShowValues = !(filter.operator === 'isAny' || filter.operator === 'onAny' || filter.operator === 'isUndefined');
const isSubFilter = filter.type === FilterType.SUB_FILTERS;
const replaceFilter = (filter) => {
props.onUpdate({
...filter,
value: [""],
filters: filter.filters ? filter.filters.map(i => ({ ...i, value: [""] })) : []
});
};
const replaceFilter = (filter) => {
props.onUpdate({
...filter,
value: [''],
filters: filter.filters ? filter.filters.map((i) => ({ ...i, value: [''] })) : [],
});
};
const onOperatorChange = (e, { name, value }) => {
props.onUpdate({ ...filter, operator: value.value })
}
const onSourceOperatorChange = (e, { name, value }) => {
props.onUpdate({ ...filter, sourceOperator: value.value })
}
const onOperatorChange = (e, { name, value }) => {
props.onUpdate({ ...filter, operator: value.value });
};
const onUpdateSubFilter = (subFilter, subFilterIndex) => {
props.onUpdate({
...filter,
filters: filter.filters.map((i, index) => {
if (index === subFilterIndex) {
return subFilter;
}
return i;
})
});
};
const onSourceOperatorChange = (e, { name, value }) => {
props.onUpdate({ ...filter, sourceOperator: value.value });
};
const onUpdateSubFilter = (subFilter, subFilterIndex) => {
props.onUpdate({
...filter,
filters: filter.filters.map((i, index) => {
if (index === subFilterIndex) {
return subFilter;
}
return i;
}),
});
};
return (
<div className="flex items-center hover:bg-active-blue -mx-5 px-5 py-2">
<div className="flex items-start w-full">
{ !isFilter && <div className="mt-1 flex-shrink-0 border w-6 h-6 text-xs flex items-center justify-center rounded-full bg-gray-light-shade mr-2">
<span>{filterIndex+1}</span>
</div> }
<FilterSelection filter={filter} onFilterClick={replaceFilter} />
{/* Filter with Source */}
{ filter.hasSource && (
<>
<FilterOperator
options={filter.sourceOperatorOptions}
onChange={onSourceOperatorChange}
className="mx-2 flex-shrink-0"
value={filter.sourceOperator}
isDisabled={filter.operatorDisabled}
/>
<FilterSource filter={filter} onUpdate={props.onUpdate} />
</>
)}
return (
<div className="flex items-center hover:bg-active-blue -mx-5 px-5 py-2">
<div className="flex items-start w-full">
{!isFilter && (
<div className="mt-1 flex-shrink-0 border w-6 h-6 text-xs flex items-center justify-center rounded-full bg-gray-light-shade mr-2">
<span>{filterIndex + 1}</span>
</div>
)}
<FilterSelection filter={filter} onFilterClick={replaceFilter} />
{/* Filter values */}
{ !isSubFilter && (
<>
<FilterOperator
options={filter.operatorOptions}
onChange={onOperatorChange}
className="mx-2 flex-shrink-0"
value={filter.operator}
isDisabled={filter.operatorDisabled}
/>
{ canShowValues && (<FilterValue filter={filter} onUpdate={props.onUpdate} />) }
</>
)}
{/* Filter with Source */}
{filter.hasSource && (
<>
<FilterOperator
options={filter.sourceOperatorOptions}
onChange={onSourceOperatorChange}
className="mx-2 flex-shrink-0"
value={filter.sourceOperator}
isDisabled={filter.operatorDisabled}
/>
<FilterSource filter={filter} onUpdate={props.onUpdate} />
</>
)}
{/* filters */}
{isSubFilter && (
<div className="grid grid-col ml-3 w-full">
{filter.filters.filter(i => (i.key !== FilterKey.FETCH_REQUEST_BODY && i.key !== FilterKey.FETCH_RESPONSE_BODY) || saveRequestPayloads).map((subFilter, subFilterIndex) => (
<SubFilterItem
filterIndex={subFilterIndex}
filter={subFilter}
onUpdate={(f) => onUpdateSubFilter(f, subFilterIndex)}
onRemoveFilter={props.onRemoveFilter}
/>
))}
</div>
)}
</div>
<div className="flex flex-shrink-0 self-start mt-1 ml-auto px-2">
<div
className="cursor-pointer p-1"
onClick={props.onRemoveFilter}
>
<Icon name="trash" size="14" />
{/* Filter values */}
{!isSubFilter && (
<>
<FilterOperator
options={filter.operatorOptions}
onChange={onOperatorChange}
className="mx-2 flex-shrink-0"
value={filter.operator}
isDisabled={filter.operatorDisabled}
/>
{canShowValues && <FilterValue filter={filter} onUpdate={props.onUpdate} />}
</>
)}
{/* filters */}
{isSubFilter && (
<div className="grid grid-col ml-3 w-full">
{filter.filters
.filter((i) => (i.key !== FilterKey.FETCH_REQUEST_BODY && i.key !== FilterKey.FETCH_RESPONSE_BODY) || saveRequestPayloads)
.map((subFilter, subFilterIndex) => (
<SubFilterItem
filterIndex={subFilterIndex}
filter={subFilter}
onUpdate={(f) => onUpdateSubFilter(f, subFilterIndex)}
onRemoveFilter={props.onRemoveFilter}
/>
))}
</div>
)}
</div>
<div className="flex flex-shrink-0 self-start mt-1 ml-auto px-2">
<div className="cursor-pointer p-1" onClick={props.onRemoveFilter}>
<Icon name="trash" size="14" />
</div>
</div>
</div>
</div>
</div>
);
);
}
export default FilterItem;
export default FilterItem;

View file

@ -59,7 +59,7 @@ function FilterList(props: Props) {
</div>
{filters.map((filter: any, filterIndex: any) => filter.isEvent ? (
<FilterItem
key={filterIndex}
key={`${filter.key}-${filterIndex}`}
filterIndex={rowIndex++}
filter={filter}
onUpdate={(filter) => props.onUpdateFilter(filterIndex, filter)}

View file

@ -5,191 +5,180 @@ import { FilterKey, FilterCategory, FilterType } from 'Types/filter/filterType';
import FilterValueDropdown from '../FilterValueDropdown';
import FilterDuration from '../FilterDuration';
import { debounce } from 'App/utils';
import { assist as assistRoute, isRoute } from "App/routes";
import { assist as assistRoute, isRoute } from 'App/routes';
const ASSIST_ROUTE = assistRoute();
interface Props {
filter: any;
onUpdate: (filter: any) => void;
filter: any;
onUpdate: (filter: any) => void;
}
function FilterValue(props: Props) {
const { filter } = props;
const [durationValues, setDurationValues] = useState({ minDuration: filter.value[0], maxDuration: filter.value.length > 1 ? filter.value[1] : filter.value[0] });
const showCloseButton = filter.value.length > 1;
const lastIndex = filter.value.length - 1;
const { filter } = props;
const [durationValues, setDurationValues] = useState({
minDuration: filter.value[0],
maxDuration: filter.value.length > 1 ? filter.value[1] : filter.value[0],
});
const showCloseButton = filter.value.length > 1;
const lastIndex = filter.value.length - 1;
const onAddValue = () => {
const newValue = filter.value.concat('');
props.onUpdate({ ...filter, value: newValue });
}
const onAddValue = () => {
const newValue = filter.value.concat('');
props.onUpdate({ ...filter, value: newValue });
};
const onRemoveValue = (valueIndex: any) => {
const newValue = filter.value.filter((_: any, index: any) => index !== valueIndex);
props.onUpdate({ ...filter, value: newValue });
}
const onRemoveValue = (valueIndex: any) => {
const newValue = filter.value.filter((_: any, index: any) => index !== valueIndex);
props.onUpdate({ ...filter, value: newValue });
};
const onChange = (e: any, item: any, valueIndex: any) => {
const newValues = filter.value.map((_: any, _index: any) => {
if (_index === valueIndex) {
return item.value;
}
return _;
})
props.onUpdate({ ...filter, value: newValues })
}
const onChange = (e: any, item: any, valueIndex: any) => {
const newValues = filter.value.map((_: any, _index: any) => {
if (_index === valueIndex) {
return item.value;
}
return _;
});
props.onUpdate({ ...filter, value: newValues });
};
const debounceOnSelect = React.useCallback(debounce(onChange, 500), [onChange]);
const debounceOnSelect = React.useCallback(debounce(onChange, 500), [onChange]);
const onDurationChange = (newValues: any) => {
setDurationValues({ ...durationValues, ...newValues });
}
const onDurationChange = (newValues: any) => {
setDurationValues({ ...durationValues, ...newValues });
};
const handleBlur = (e: any) => {
if (filter.type === FilterType.DURATION) {
const { maxDuration, minDuration, key } = filter;
if (maxDuration || minDuration) return;
if (maxDuration !== durationValues.maxDuration ||
minDuration !== durationValues.minDuration) {
props.onUpdate({ ...filter, value: [durationValues.minDuration, durationValues.maxDuration] });
}
}
}
const handleBlur = (e: any) => {
if (filter.type === FilterType.DURATION) {
const { maxDuration, minDuration, key } = filter;
if (maxDuration || minDuration) return;
if (maxDuration !== durationValues.maxDuration || minDuration !== durationValues.minDuration) {
props.onUpdate({ ...filter, value: [durationValues.minDuration, durationValues.maxDuration] });
}
}
};
const getParms = (key: any) => {
let params: any = { type: filter.key };
switch (filter.category) {
case FilterCategory.METADATA:
params = { type: FilterKey.METADATA, key: key };
}
const getParms = (key: any) => {
let params: any = { type: filter.key };
switch (filter.category) {
case FilterCategory.METADATA:
params = { type: FilterKey.METADATA, key: key };
}
if (isRoute(ASSIST_ROUTE, window.location.pathname)) {
params = { ...params, live: true };
}
if (isRoute(ASSIST_ROUTE, window.location.pathname)) {
params = { ...params, live: true };
}
return params;
}
return params;
};
const renderValueFiled = (value: any, valueIndex: any) => {
const showOrButton = valueIndex === lastIndex && filter.type !== FilterType.NUMBER;
switch(filter.type) {
case FilterType.STRING:
return (
<FilterAutoCompleteLocal
value={value}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
onSelect={(e, item) => debounceOnSelect(e, item, valueIndex)}
icon={filter.icon}
/>
)
case FilterType.DROPDOWN:
return (
<FilterValueDropdown
// search={true}
value={value}
filter={filter}
options={filter.options}
onChange={({ value }) => onChange(null, { value }, valueIndex)}
/>
)
case FilterType.ISSUE:
case FilterType.MULTIPLE_DROPDOWN:
return (
<FilterValueDropdown
search={true}
// multiple={true}
value={value}
// filter={filter}
options={filter.options}
onChange={({ value }) => onChange(null, { value }, valueIndex)}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
/>
)
case FilterType.DURATION:
return (
<FilterDuration
onChange={ onDurationChange }
// onEnterPress={ this.handleClose }
onBlur={handleBlur}
minDuration={ durationValues.minDuration }
maxDuration={ durationValues.maxDuration }
/>
)
case FilterType.NUMBER_MULTIPLE:
return (
<FilterAutoCompleteLocal
value={value}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
onSelect={(e, item) => debounceOnSelect(e, item, valueIndex)}
icon={filter.icon}
type="number"
/>
)
case FilterType.NUMBER:
return (
<FilterAutoCompleteLocal
value={value}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
onSelect={(e, item) => debounceOnSelect(e, item, valueIndex)}
icon={filter.icon}
type="number"
allowDecimals={false}
isMultilple={false}
/>
// <input
// className="w-full px-2 py-1 text-sm leading-tight text-gray-700 rounded bg-white border"
// type="number"
// name={`${filter.key}-${valueIndex}`}
// value={value}
// placeholder="Enter"
// onChange={(e) => onChange(e, { value: e.target.value }, valueIndex)}
// />
)
case FilterType.MULTIPLE:
return (
<FilterAutoComplete
value={value}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
method={'GET'}
endpoint='/events/search'
params={getParms(filter.key)}
headerText={''}
// placeholder={''}
onSelect={(e, item) => onChange(e, item, valueIndex)}
icon={filter.icon}
/>
)
}
}
const renderValueFiled = (value: any, valueIndex: any) => {
const showOrButton = valueIndex === lastIndex && filter.type !== FilterType.NUMBER;
switch (filter.type) {
case FilterType.STRING:
return (
<FilterAutoCompleteLocal
value={value}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
onSelect={(e, item) => debounceOnSelect(e, item, valueIndex)}
icon={filter.icon}
/>
);
case FilterType.DROPDOWN:
return (
<FilterValueDropdown
// search={true}
value={value}
filter={filter}
options={filter.options}
onChange={({ value }) => onChange(null, { value }, valueIndex)}
/>
);
case FilterType.ISSUE:
case FilterType.MULTIPLE_DROPDOWN:
return (
<FilterValueDropdown
search={true}
// multiple={true}
value={value}
// filter={filter}
options={filter.options}
onChange={({ value }) => onChange(null, { value }, valueIndex)}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
/>
);
case FilterType.DURATION:
return (
<FilterDuration
onChange={onDurationChange}
// onEnterPress={ this.handleClose }
onBlur={handleBlur}
minDuration={durationValues.minDuration}
maxDuration={durationValues.maxDuration}
/>
);
case FilterType.NUMBER_MULTIPLE:
return (
<FilterAutoCompleteLocal
value={value}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
onSelect={(e, item) => debounceOnSelect(e, item, valueIndex)}
icon={filter.icon}
type="number"
/>
);
case FilterType.NUMBER:
return (
<FilterAutoCompleteLocal
value={value}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
onSelect={(e, item) => debounceOnSelect(e, item, valueIndex)}
icon={filter.icon}
type="number"
allowDecimals={false}
isMultilple={false}
/>
);
case FilterType.MULTIPLE:
return (
<FilterAutoComplete
value={value}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
method={'GET'}
endpoint="/events/search"
params={getParms(filter.key)}
headerText={''}
// placeholder={''}
onSelect={(e, item) => onChange(e, item, valueIndex)}
icon={filter.icon}
/>
);
}
};
return (
<div className="grid grid-cols-3 gap-3 w-full">
{ filter.type === FilterType.DURATION ? (
renderValueFiled(filter.value, 0)
) : (
filter.value && filter.value.map((value: any, valueIndex: any) => (
<div key={valueIndex}>
{renderValueFiled(value, valueIndex)}
</div>
))
)}
</div>
);
return (
<div className="grid grid-cols-3 gap-3 w-full">
{filter.type === FilterType.DURATION
? renderValueFiled(filter.value, 0)
: filter.value &&
filter.value.map((value: any, valueIndex: any) => <div key={valueIndex}>{renderValueFiled(value, valueIndex)}</div>)}
</div>
);
}
export default FilterValue;
export default FilterValue;