@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
127 lines (126 loc) • 4.71 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
import { runIfNotResolvedIn } from '../../../Utilities/runIfNotResolvedIn';
import { useAdaptable } from '../../AdaptableContext';
import { useCallback } from 'react';
import { MultiCombobox, SingleCombobox, } from '../../../components/Combobox';
export const PermittedValuesSelector = function (props) {
const adaptable = useAdaptable();
const [refetchKey, setRefetchKey] = React.useState(0);
const [isLoading, setIsLoading] = React.useState(true);
const [options, setOptions] = React.useState([]);
const searchFilterRef = React.useRef('');
const [searchValueWasUsedWhenFiltering, setSearchValueWasUsedWhenFiltering] = React.useState(false);
const dataType = React.useMemo(() => {
return adaptable.api.columnApi.getColumnDataTypeForColumnId(props.columnId);
}, [props.columnId]);
React.useEffect(() => {
if (!props.columnId) {
setIsLoading(false);
return;
}
setIsLoading(true);
(async () => {
let searchValueUsedInFilterValue = false;
const currentSearchValue = searchFilterRef.current;
const p = props.loadValues
? props.loadValues({
get currentSearchValue() {
searchValueUsedInFilterValue = true;
return currentSearchValue;
},
})
: adaptable.api.filterApi.columnFilterApi.internalApi.getColumnFilterValues({
columnId: props.columnId,
get currentSearchValue() {
searchValueUsedInFilterValue = true;
return currentSearchValue;
},
});
const distinctColumnValues = await runIfNotResolvedIn(p, () => {
setIsLoading(true);
});
setSearchValueWasUsedWhenFiltering(searchValueUsedInFilterValue);
setIsLoading(false);
setOptions(Array.isArray(distinctColumnValues) ? distinctColumnValues : distinctColumnValues.values);
})();
}, [props.columnId, props.loadValues, refetchKey]);
const isCreatable = (props.allowNewValues && !dataType) || ['text', 'number'].includes(dataType);
const handleSingleValueChange = (value) => {
if (isCreatable) {
if (!dataType && typeof value === 'string' && !isNaN(parseFloat(value))) {
props.onChange(parseFloat(value));
}
else if (dataType === 'number') {
let num = parseFloat(value);
num = isNaN(num) ? null : num;
props.onChange(num);
}
else {
props.onChange(value);
}
}
else {
props.onChange(value);
}
};
const handleMultiValueChange = (values) => {
if (isCreatable) {
if (dataType === 'number') {
const nums = values.map((v) => parseFloat(v)).filter((v) => !isNaN(v));
props.onChange(nums);
}
else {
props.onChange(values);
}
}
else {
props.onChange(values);
}
};
const handleOnChange = (value) => {
if (props.isMulti) {
handleMultiValueChange(value);
}
else {
handleSingleValueChange(value);
}
};
const reload = useCallback(() => {
setRefetchKey((k) => k + 1);
}, []);
const onInputChange = (value) => {
searchFilterRef.current = value;
if (searchValueWasUsedWhenFiltering) {
reload();
}
};
const comboBoxProps = {
['aria-label']: 'Permitted Values Selector',
searchable: props.searchable ?? 'menulist',
className: props.className,
disabled: props.disabled,
placeholder: props.placeholder || (props.allowNewValues ? 'Select or type new value' : 'Select value'),
['data-name']: 'permitted-values-selector',
items: options,
onInputValueChange: onInputChange,
onValueChange: handleOnChange,
value: props.value ?? '',
onOpenChange: (open) => {
if (open) {
reload();
}
},
isCreatable,
isLoading,
virtualized: true,
resizable: true,
showClear: true,
onFocus: props.onFocus,
onBlur: props.onBlur,
};
if (props.isMulti) {
return _jsx(MultiCombobox, { ...comboBoxProps });
}
return (_jsx(SingleCombobox, { ...comboBoxProps }));
};