diff --git a/packages/filterparser/src/filterTool.ts b/packages/filterparser/src/filterTool.ts index 7a1aa3e51..0947ddaf9 100644 --- a/packages/filterparser/src/filterTool.ts +++ b/packages/filterparser/src/filterTool.ts @@ -1,4 +1,44 @@ +export type FilterMultipleValuesMode = 'is' | 'is_not' | 'contains' | 'begins' | 'ends'; + export function getFilterValueExpression(value) { if (value == null) return 'NULL'; return `="${value}"`; } + +export function createMultiLineFilter(mode: FilterMultipleValuesMode, text: string) { + let res = ''; + for (let line of text.split('\n')) { + line = line.trim(); + if (line.length == 0) continue; + + if (res.length > 0) { + switch (mode) { + case 'is_not': + res += ' '; + break; + default: + res += ','; + break; + } + } + + switch (mode) { + case 'is': + res += "='" + line + "'"; + break; + case 'is_not': + res += "<>'" + line + "'"; + break; + case 'contains': + res += "'" + line + "'"; + break; + case 'begins': + res += "^'" + line + "'"; + break; + case 'ends': + res += "$'" + line + "'"; + break; + } + } + return res; +} diff --git a/packages/web/src/datagrid/DataFilterControl.js b/packages/web/src/datagrid/DataFilterControl.js index ada9d8ffb..9f9c8f88a 100644 --- a/packages/web/src/datagrid/DataFilterControl.js +++ b/packages/web/src/datagrid/DataFilterControl.js @@ -3,8 +3,10 @@ import React from 'react'; import { DropDownMenuItem, DropDownMenuDivider, showMenu } from '../modals/DropDownMenu'; import styled from 'styled-components'; import keycodes from '../utility/keycodes'; -import { parseFilter } from '@dbgate/filterparser'; +import { parseFilter, createMultiLineFilter } from '@dbgate/filterparser'; import InlineButton from '../widgets/InlineButton'; +import showModal from '../modals/showModal'; +import FilterMultipleValuesModal from '../modals/FilterMultipleValuesModal'; // import { $ } from '../../Utility/jquery'; // import autobind from 'autobind-decorator'; // import * as React from 'react'; @@ -36,7 +38,7 @@ const FilterDiv = styled.div` const FilterInput = styled.input` flex: 1; min-width: 10px; - background-color: ${props => (props.state == 'ok' ? '#CCFFCC' : props.state == 'error' ? '#FFCCCC' : 'white')}; + background-color: ${(props) => (props.state == 'ok' ? '#CCFFCC' : props.state == 'error' ? '#FFCCCC' : 'white')}; `; // const FilterButton = styled.button` // color: gray; @@ -47,68 +49,68 @@ function DropDownContent({ filterType, setFilter, filterMultipleValues, openFilt case 'number': return ( <> - setFilter('')}>Clear Filter - filterMultipleValues()}>Filter multiple values - openFilterWindow('=')}>Equals... - openFilterWindow('<>')}>Does Not Equal... - setFilter('NULL')}>Is Null - setFilter('NOT NULL')}>Is Not Null - openFilterWindow('>')}>Greater Than... - openFilterWindow('>=')}>Greater Than Or Equal To... - openFilterWindow('<')}>Less Than... - openFilterWindow('<=')}>Less Than Or Equal To... + setFilter('')}>Clear Filter + filterMultipleValues()}>Filter multiple values + openFilterWindow('=')}>Equals... + openFilterWindow('<>')}>Does Not Equal... + setFilter('NULL')}>Is Null + setFilter('NOT NULL')}>Is Not Null + openFilterWindow('>')}>Greater Than... + openFilterWindow('>=')}>Greater Than Or Equal To... + openFilterWindow('<')}>Less Than... + openFilterWindow('<=')}>Less Than Or Equal To... ); case 'logical': return ( <> - setFilter('')}>Clear Filter - filterMultipleValues()}>Filter multiple values - setFilter('NULL')}>Is Null - setFilter('NOT NULL')}>Is Not Null - setFilter('TRUE')}>Is True - setFilter('FALSE')}>Is False - setFilter('TRUE, NULL')}>Is True or NULL - setFilter('FALSE, NULL')}>Is False or NULL + setFilter('')}>Clear Filter + filterMultipleValues()}>Filter multiple values + setFilter('NULL')}>Is Null + setFilter('NOT NULL')}>Is Not Null + setFilter('TRUE')}>Is True + setFilter('FALSE')}>Is False + setFilter('TRUE, NULL')}>Is True or NULL + setFilter('FALSE, NULL')}>Is False or NULL ); case 'datetime': return ( <> - setFilter('')}>Clear Filter - filterMultipleValues()}>Filter multiple values - setFilter('NULL')}>Is Null - setFilter('NOT NULL')}>Is Not Null + setFilter('')}>Clear Filter + filterMultipleValues()}>Filter multiple values + setFilter('NULL')}>Is Null + setFilter('NOT NULL')}>Is Not Null - openFilterWindow('<=')}>Before... - openFilterWindow('>=')}>After... - openFilterWindow('>=;<=')}>Between... + openFilterWindow('<=')}>Before... + openFilterWindow('>=')}>After... + openFilterWindow('>=;<=')}>Between... - setFilter('TOMORROW')}>Tomorrow - setFilter('TODAY')}>Today - setFilter('YESTERDAY')}>Yesterday + setFilter('TOMORROW')}>Tomorrow + setFilter('TODAY')}>Today + setFilter('YESTERDAY')}>Yesterday - setFilter('NEXT WEEK')}>Next Week - setFilter('THIS WEEK')}>This Week - setFilter('LAST WEEK')}>Last Week + setFilter('NEXT WEEK')}>Next Week + setFilter('THIS WEEK')}>This Week + setFilter('LAST WEEK')}>Last Week - setFilter('NEXT MONTH')}>Next Month - setFilter('THIS MONTH')}>This Month - setFilter('LAST MONTH')}>Last Month + setFilter('NEXT MONTH')}>Next Month + setFilter('THIS MONTH')}>This Month + setFilter('LAST MONTH')}>Last Month - setFilter('NEXT YEAR')}>Next Year - setFilter('THIS YEAR')}>This Year - setFilter('LAST YEAR')}>Last Year + setFilter('NEXT YEAR')}>Next Year + setFilter('THIS YEAR')}>This Year + setFilter('LAST YEAR')}>Last Year @@ -140,24 +142,24 @@ function DropDownContent({ filterType, setFilter, filterMultipleValues, openFilt case 'string': return ( <> - setFilter('')}>Clear Filter - filterMultipleValues()}>Filter multiple values + setFilter('')}>Clear Filter + filterMultipleValues()}>Filter multiple values - openFilterWindow('=')}>Equals... - openFilterWindow('<>')}>Does Not Equal... - setFilter('NULL')}>Is Null - setFilter('NOT NULL')}>Is Not Null - setFilter('EMPTY, NULL')}>Is Empty Or Null - setFilter('NOT EMPTY NOT NULL')}>Has Not Empty Value + openFilterWindow('=')}>Equals... + openFilterWindow('<>')}>Does Not Equal... + setFilter('NULL')}>Is Null + setFilter('NOT NULL')}>Is Not Null + setFilter('EMPTY, NULL')}>Is Empty Or Null + setFilter('NOT EMPTY NOT NULL')}>Has Not Empty Value - openFilterWindow('+')}>Contains... - openFilterWindow('~')}>Does Not Contain... - openFilterWindow('^')}>Begins With... - openFilterWindow('!^')}>Does Not Begin With... - openFilterWindow('$')}>Ends With... - openFilterWindow('!$')}>Does Not End With... + openFilterWindow('+')}>Contains... + openFilterWindow('~')}>Does Not Contain... + openFilterWindow('^')}>Begins With... + openFilterWindow('!^')}>Does Not Begin With... + openFilterWindow('$')}>Ends With... + openFilterWindow('!$')}>Does Not End With... ); } @@ -165,7 +167,7 @@ function DropDownContent({ filterType, setFilter, filterMultipleValues, openFilt export default function DataFilterControl({ isReadOnly = false, filterType, filter, setFilter }) { const [filterState, setFilterState] = React.useState('empty'); - const setFilterText = filter => { + const setFilterText = (filter) => { setFilter(filter); editorRef.current.value = filter || ''; updateFilterState(); @@ -174,12 +176,19 @@ export default function DataFilterControl({ isReadOnly = false, filterType, filt if ((filter || '') == (editorRef.current.value || '')) return; setFilter(editorRef.current.value); }; - const filterMultipleValues = () => {}; - const openFilterWindow = operator => {}; + const filterMultipleValues = () => { + showModal((modalState) => ( + setFilterText(createMultiLineFilter(mode, text))} + /> + )); + }; + const openFilterWindow = (operator) => {}; const buttonRef = React.useRef(); const editorRef = React.useRef(); - const handleKeyDown = ev => { + const handleKeyDown = (ev) => { if (isReadOnly) return; if (ev.keyCode == keycodes.enter) { applyFilter(); diff --git a/packages/web/src/modals/FilterMultipleValuesModal.js b/packages/web/src/modals/FilterMultipleValuesModal.js index e69de29bb..f0056070d 100644 --- a/packages/web/src/modals/FilterMultipleValuesModal.js +++ b/packages/web/src/modals/FilterMultipleValuesModal.js @@ -0,0 +1,70 @@ +import React from 'react'; +import ModalBase from './ModalBase'; +import FormStyledButton from '../widgets/FormStyledButton'; +import styled from 'styled-components'; +import { FontIcon } from '../icons'; +import { FormButtonRow, FormSubmit } from '../utility/forms'; +import ModalHeader from './ModalHeader'; +import ModalFooter from './ModalFooter'; +import ModalContent from './ModalContent'; + +const Wrapper = styled.div` + display: flex; +`; + +const OptionsWrapper = styled.div` + margin-left: 10px; +`; + +function RadioGroupItem({ text, value, defaultChecked = undefined, setMode }) { + return ( +
+ setMode(value)} + /> + +
+ ); +} + +export default function FilterMultipleValuesModal({ modalState, onFilter }) { + const editorRef = React.useRef(null); + const [text, setText] = React.useState(''); + const [mode, setMode] = React.useState('is'); + React.useEffect(() => { + setTimeout(() => { + if (editorRef.current) editorRef.current.focus(); + }, 1); + }, []); + + const handleOk = () => { + onFilter(mode, text); + modalState.close(); + }; + + return ( + + Filter multiple values + + +