UNPKG

@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
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')))))); };