@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
118 lines (117 loc) • 5.94 kB
JavaScript
import * as React from 'react';
import { DragDropContext } from '../../dnd';
import { Box, Flex } from 'rebass';
import { mapExpressionToQlPredicate, } from '../../../parser/src/predicate';
import { mapQlPredicateToExpression } from '../../../parser/src/predicate/mapQlPredicateToExpression';
import { useAdaptable } from '../../../View/AdaptableContext';
import ErrorBox from '../../ErrorBox';
import HelpBlock from '../../HelpBlock';
import Panel from '../../Panel';
import SimpleButton from '../../SimpleButton';
import { WarningBox } from '../../WarningBox';
import { QueryPredicateBuilder } from './QueryPredicateBuilder';
import { getFunctionsForColumnType, getUnsuportedExpressionFromQlPredicate, reorder, } from './utils';
const QUERY_BUILDER_CLASSNAME = 'ab-QueryBuilder';
const QueryBuilderContext = React.createContext(null);
export function useQueryBuilderContext() {
const context = React.useContext(QueryBuilderContext);
if (!context) {
throw new Error('useQueryBuilderContext must be used within a QueryBuilderContext');
}
return context;
}
export const QueryBuilder = (props) => {
const adaptable = useAdaptable();
const [qlPredicate, setQlPredicate] = React.useState(() => {
const qlPredicate = mapExpressionToQlPredicate(props.query);
return qlPredicate;
});
const [expressionStr, setExpressionStr] = React.useState(props.query);
const handleQlPredicateChange = (qlPredicate) => {
setQlPredicate(qlPredicate);
if (qlPredicate && !('errorMessage' in qlPredicate)) {
const newQuery = mapQlPredicateToExpression(qlPredicate);
props.onChange(newQuery);
setExpressionStr(newQuery);
}
};
const clearExpression = () => {
const predicate = mapExpressionToQlPredicate('');
setQlPredicate(predicate);
setExpressionStr('');
props.onChange('');
};
const booleanExpressions = React.useMemo(() => {
const expressionMap = adaptable.api.internalApi
.getQueryLanguageService()
.getModuleExpressionFunctionsMap(props.module);
const booleanExpressions = { ...expressionMap.booleanFunctions };
const booleanExpressionsWithoutCombinators = booleanExpressions;
delete booleanExpressionsWithoutCombinators.AND;
delete booleanExpressionsWithoutCombinators.OR;
return booleanExpressionsWithoutCombinators;
}, []);
const context = React.useMemo(() => {
return {
getColumns: props.getColumns,
getFields: props.getFields,
getExpressions: (columnType) => {
return booleanExpressions
? getFunctionsForColumnType(columnType, Object.keys(booleanExpressions))
: [];
},
onQlPredicateChange: handleQlPredicateChange,
};
}, []);
const clearExpressionButton = (React.createElement(SimpleButton, { onClick: () => {
clearExpression();
} }, "Clear Expression"));
const unsupportedExpressionFunction = getUnsuportedExpressionFromQlPredicate(qlPredicate, {
supportedFields: props.getFields(),
});
let errorOrEditor = null;
if (qlPredicate && 'errorMessage' in qlPredicate) {
errorOrEditor = props.query?.includes?.('QUERY') ? (React.createElement(WarningBox, { "data-name": "unsupported-query-warning" },
React.createElement(Flex, { alignItems: "center" },
"Named Queries are not supported in the Query Builder",
React.createElement(Box, { flex: 1 }),
clearExpressionButton))) : (React.createElement(ErrorBox, null,
React.createElement(Flex, null,
qlPredicate.errorMessage,
React.createElement(Box, { flex: 1 }),
clearExpressionButton)));
}
else if (unsupportedExpressionFunction) {
errorOrEditor = (React.createElement(WarningBox, { "data-name": "unsupported-expression-warning" }, unsupportedExpressionFunction));
}
else if (qlPredicate && !('errorMessage' in qlPredicate)) {
errorOrEditor = (React.createElement(QueryPredicateBuilder, { isRoot: true, index: 0, id: "0", predicate: qlPredicate, onNewPredicate: (type) => {
// add to its children
const newPredicate = {
operator: type === 'filter' ? undefined : 'AND',
args: [],
};
handleQlPredicateChange({
...qlPredicate,
args: [...qlPredicate.args, newPredicate],
});
}, onChange: (predicate) => {
handleQlPredicateChange(predicate);
} }));
}
return (React.createElement(DragDropContext, { onDragEnd: (result) => {
if (!result.destination) {
return;
}
const toPath = `${result.destination.droppableId}/${result.destination.index}`;
const fromPath = result.draggableId;
const predicate = reorder(qlPredicate, fromPath, toPath);
handleQlPredicateChange(predicate);
} },
React.createElement(QueryBuilderContext.Provider, { value: context },
React.createElement(Box, { className: QUERY_BUILDER_CLASSNAME },
React.createElement(HelpBlock, { "data-name": "query-builder-help", mt: 2, mb: 2, p: 2, fontSize: 3 }, "Build the Grid Filter by adding Column Conditions and AND / OR Groups as required"),
errorOrEditor,
React.createElement(Panel, { "data-name": "query-builder-expression-preview", variant: "default", header: "AdapTableQL Expression", mt: 3 },
React.createElement(Box, { className: `${QUERY_BUILDER_CLASSNAME}__expression`, minHeight: 48, my: 2, p: 3 }, expressionStr || 'Output Expression will display here'))))));
};