@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
191 lines (190 loc) • 9.79 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React from 'react';
import { getQlPredicateSymbol } from '../../../parser/src/predicate/mapQlPredicateToExpression';
import { mapExpressionFunctionTypeToColumnDataType } from '../../../Utilities/adaptableQlUtils';
import { useAdaptable } from '../../../View/AdaptableContext';
import AdaptableInput from '../../../View/Components/AdaptableInput';
import { ColumnSelector } from '../../../View/Components/Selectors/ColumnSelector';
import { FieldSelector } from '../../../View/Components/Selectors/FieldSelector';
import { PermittedValuesSelector } from '../../../View/Components/Selectors/PermittedValuesSelector';
import { CheckBox } from '../../CheckBox';
import { NewDropdownButton } from '../../DropdownButton';
import { Icon } from '../../icons';
import { InputGroup } from '../../InputGroup';
import { useQueryBuilderContext } from './QueryBuilder';
import { isFieldValue, mapColumnExpressionToColumnId, mapExpressionToFieldValue, mapFieldValueToExpression, } from './utils';
import { Box, Flex } from '../../Flex';
import { SingleSelect } from '../../NewSelect';
export const PrimitiveColumnOrFieldSelector = (props) => {
const adaptable = useAdaptable();
const [type, setType] = React.useState(() => {
return (!props.fieldOrColumn || props.fieldOrColumn.includes('[') ? 'column' : 'field');
});
const hasFields = React.useMemo(() => {
return adaptable.api.expressionApi.internalApi.getAvailableFields()?.length > 0;
}, []);
const hasFieldsOrValueIsField = hasFields || isFieldValue(props.fieldOrColumn);
let input = null;
if (type === 'column') {
const columnId = mapColumnExpressionToColumnId(props.fieldOrColumn);
input = (_jsx(ColumnSelector, { value: columnId, type: props.type, onChange: (columnId) => {
props.onChange(`[${columnId}]`);
} }));
}
else {
input = (_jsx(FieldSelector, { value: mapExpressionToFieldValue(props.fieldOrColumn), type: props.type, onChange: (fieldValue) => {
props.onChange(mapFieldValueToExpression(fieldValue));
} }));
}
const typeOptions = [
{
label: (_jsxs(Flex, { alignItems: "center", children: [_jsx(Icon, { name: "grid" }), _jsx(Box, { className: "twa:ml-2", children: "Column" })] })),
value: 'column',
icon: 'grid',
},
{
label: (_jsxs(Flex, { alignItems: "center", children: [_jsx(Icon, { name: "column-outline" }), _jsx(Box, { className: "twa:ml-2", children: "Field" })] })),
value: 'field',
icon: 'column-outline',
},
];
return !hasFieldsOrValueIsField || props.hideFields ? (_jsx(Box, { children: input })) : (_jsxs(InputGroup, { Component: Flex, "data-id": "query-first-arg-wrapper", children: [_jsx(SingleSelect, { className: "twa:min-w-32", value: type, items: typeOptions, onValueChange: (value) => {
props.onChange(null);
setType(value);
} }), _jsx("div", { className: "twa:w-0.5" }), input] }));
};
export const PrimitiveValueInput = (props) => {
const adaptable = useAdaptable();
const hasFields = React.useMemo(() => {
return adaptable.api.expressionApi.internalApi.getAvailableFields()?.length > 0;
}, []);
const hasFieldsOrValueIsField = hasFields || isFieldValue(props.value);
const [type, setType] = React.useState(() => {
if (typeof props?.value === 'string' && props?.value?.includes('[')) {
return 'column-name';
}
if (typeof props?.value === 'string' && props?.value?.includes('FIELD')) {
return 'field';
}
return 'input-value';
});
const handleTypeChange = (newType) => {
if (type !== newType) {
props.onChange(undefined);
setType(newType);
}
};
const getEditor = () => {
const common = {
'data-id': 'query-input',
};
switch (props.inputType) {
case 'boolean':
return (_jsx(CheckBox, { ...common, checked: props.value, onChange: () => props.onChange(!props.value) }));
case 'number':
return (_jsx(AdaptableInput, { ...common, type: "number", value: props.value ?? '', onChange: (event) => {
const value = event.target.value;
if (value === '') {
props.onChange(undefined);
}
else {
props.onChange(parseFloat(value));
}
} }));
case 'text':
return (_jsx(AdaptableInput, { ...common, type: "text", value: props.value ?? '', onChange: (event) => {
props.onChange(event.target.value);
} }));
case 'date':
const dateStr = typeof props.value === 'string' ? props.value.replace('DATE(', '').replace(')', '') : '';
return (_jsx(AdaptableInput, { ...common, type: "date", value: dateStr ?? '', onChange: (event) => {
const stringified = `DATE("${event.target.value}")`;
props.onChange(stringified);
} }));
default:
return _jsx(_Fragment, {});
}
};
let editor = null;
if (type === 'column-name') {
const abColType = mapExpressionFunctionTypeToColumnDataType(props.inputType);
editor = (_jsx(PrimitiveColumnOrFieldSelector, { hideFields: true, fieldOrColumn: props.value, type: abColType, onChange: (columnId) => {
props.onChange(columnId);
} }));
}
else if (type === 'field') {
editor = (_jsx(FieldSelector, { value: mapExpressionToFieldValue(props.value), onChange: (fieldValue) => {
props.onChange(mapFieldValueToExpression(fieldValue));
} }));
}
else if (!['date', 'boolean'].includes(props.inputType)) {
editor = (_jsx(PermittedValuesSelector, { allowNewValues: true, searchable: 'inline', value: props.value, columnId: mapColumnExpressionToColumnId(props.lefthandColumnIdParam), onChange: (value) => {
props.onChange(value);
} }));
}
else {
editor = getEditor();
}
const options = [
{
label: (_jsxs(Flex, { alignItems: "center", children: [_jsx(Icon, { name: "columns" }), _jsx(Box, { className: "twa:ml-2", children: "Column" })] })),
icon: 'columns',
value: 'column-name',
},
{
label: (_jsxs(Flex, { alignItems: "center", children: [_jsx(Icon, { name: "edit" }), _jsx(Box, { className: "twa:ml-2", children: "Value" })] })),
icon: 'edit',
value: 'input-value',
},
];
if (hasFieldsOrValueIsField || type === 'field') {
options.push({
label: (_jsxs(Flex, { alignItems: "center", children: [_jsx(Icon, { name: "column-outline" }), _jsx(Box, { className: "twa:ml-2", children: "Field" })] })),
icon: 'column-outline',
value: 'field',
});
}
const typeOption = options.find((option) => option.value === type);
return (_jsxs(Flex, { "data-id": "query-input-wrapper", className: "twa:mr-2 twa:gap-0.5 twa:flex-1", children: [_jsx(SingleSelect, { className: "twa:min-w-28", value: typeOption.value, items: options, onValueChange: (value) => handleTypeChange(value) }), _jsx("div", { className: "twa:flex-1 twa:flex twa:min-w-32", children: editor })] }));
};
export const PrimitiveMultiValueInput = (props) => {
return (_jsx(PermittedValuesSelector, { isMulti: true, allowNewValues: true, value: props.value, columnId: mapColumnExpressionToColumnId(props.lefthandColumnIdParam), onChange: (value) => {
props.onChange(value);
} }));
};
const SymbolToIcon = (props) => {
switch (props.symbol) {
case '=':
return _jsx(Icon, { name: "equals" });
case '!=':
return _jsx(Icon, { name: "not-equal" });
case '>':
return _jsx(Icon, { name: "greater-than" });
case '>=':
return _jsx(Icon, { name: "greater-than-or-equal" });
case '<':
return _jsx(Icon, { name: "less-than" });
case '<=':
return _jsx(Icon, { name: "less-than-or-equal" });
default:
return _jsx(_Fragment, { children: props.symbol });
}
};
export const ExpressionSelector = (props) => {
const { getExpressions } = useQueryBuilderContext();
const expressions = props.dataType ? getExpressions(props.dataType) : [];
return (_jsx(NewDropdownButton, { "data-id": "expression-selector", className: "twa:min-h-input", "data-value": props.value, variant: "raised", tone: 'accent', items: expressions.map((expression) => ({
label: _jsx(SymbolToIcon, { symbol: getQlPredicateSymbol(expression) }),
onClick: () => {
if (expression !== props.value) {
props.onExpressionChange(expression);
}
},
})), children: _jsx(SymbolToIcon, { symbol: getQlPredicateSymbol(props.value) ?? 'Select Operator' }) }));
};
export const CombinatorSelector = (props) => {
return (_jsx(NewDropdownButton, { className: "twa:min-h-input", "data-id": "combinator-selector", "data-value": props.value, variant: "raised", tone: "accent", items: [
{ label: 'AND', onClick: () => props.onChange('AND') },
{ label: 'OR', onClick: () => props.onChange('OR') },
], children: props.value }));
};