diff --git a/assets/icons/equalicon.svg b/assets/icons/equalicon.svg new file mode 100644 index 0000000..5f4db9f --- /dev/null +++ b/assets/icons/equalicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/greaterthanicon.svg b/assets/icons/greaterthanicon.svg new file mode 100644 index 0000000..5fc932d --- /dev/null +++ b/assets/icons/greaterthanicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/greaterthanorequaltoicon.svg b/assets/icons/greaterthanorequaltoicon.svg new file mode 100644 index 0000000..9c49492 --- /dev/null +++ b/assets/icons/greaterthanorequaltoicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/lessthanicon.svg b/assets/icons/lessthanicon.svg new file mode 100644 index 0000000..d0ecfd8 --- /dev/null +++ b/assets/icons/lessthanicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/lessthanorequaltoicon.svg b/assets/icons/lessthanorequaltoicon.svg new file mode 100644 index 0000000..5094130 --- /dev/null +++ b/assets/icons/lessthanorequaltoicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/notequalicon.svg b/assets/icons/notequalicon.svg new file mode 100644 index 0000000..a0ac9dd --- /dev/null +++ b/assets/icons/notequalicon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/components/Dashboard/common/FilterInput.jsx b/src/components/Dashboard/common/FilterInput.jsx index 3dd0e03..b3b4bbb 100644 --- a/src/components/Dashboard/common/FilterInput.jsx +++ b/src/components/Dashboard/common/FilterInput.jsx @@ -1,4 +1,11 @@ -import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react' +import { + useCallback, + useContext, + useEffect, + useMemo, + useRef, + useState +} from 'react' import { ConfigProvider, Popover, Tag, theme } from 'antd' import { CloseCircleFilled } from '@ant-design/icons' import PropTypes from 'prop-types' @@ -11,19 +18,58 @@ import useStyle, { useSharedStyle } from 'antd/es/input/style' import { useThemeContext } from '../context/ThemeContext' import SimplePropertyFilter from './SimplePropertyFilter' import ScrollBox from './ScrollBox' +import ArrowLeftIcon from '../../Icons/ArrowLeftIcon' +import GreaterThanIcon from '../../Icons/GreaterThanIcon' +import GreaterThanOrEqualToIcon from '../../Icons/GreaterThanOrEqualToIcon' +import LessThanIcon from '../../Icons/LessThanIcon' +import LessThanOrEqualToIcon from '../../Icons/LessThanOrEqualToIcon' +import NotEqualIcon from '../../Icons/NotEqualIcon' +import EqualIcon from '../../Icons/EqualIcon' + +const operandIconStyle = { fontSize: 8 } // Longer symbols first so ".." / "<>" / ">=" match before "." / "<" / ">". // Wildcards (* ?) and @ stay as plain text — they are not operands. const OPERANDS = [ - { symbol: '..', label: 'TO', color: 'cyan' }, - { symbol: '<>', label: '≠', color: 'volcano' }, - { symbol: '>=', label: '> OR =', color: 'orange' }, - { symbol: '<=', label: '< OR =', color: 'orange' }, + { + symbol: '..', + label: , + color: 'cyan' + }, + { + symbol: '<>', + label: , + color: 'volcano' + }, + { + symbol: '>=', + label: , + color: 'orange' + }, + { + symbol: '<=', + label: , + color: 'orange' + }, { symbol: '|', label: 'OR', color: 'purple' }, { symbol: '&', label: 'AND', color: 'purple' }, - { symbol: '>', label: '>', color: 'orange' }, - { symbol: '<', label: '<', color: 'orange' }, - { symbol: '=', label: '=', color: 'blue' } + { + symbol: '>', + label: ( + + ), + color: 'orange' + }, + { + symbol: '<', + label: , + color: 'orange' + }, + { + symbol: '=', + label: , + color: 'blue' + } ] const OPERAND_BY_SYMBOL = Object.fromEntries( @@ -101,7 +147,8 @@ const getOffsetAt = (root, targetNode, targetOffset, chipSnap = 'end') => { if (node.nodeType === Node.TEXT_NODE) { offset += targetOffset } else if (node.getAttribute?.('data-operand') != null) { - offset += targetOffset <= 0 ? 0 : node.getAttribute('data-operand').length + offset += + targetOffset <= 0 ? 0 : node.getAttribute('data-operand').length } else { for (let i = 0; i < targetOffset; i += 1) { offset += nodeLength(node.childNodes[i]) @@ -421,7 +468,10 @@ const FilterInput = ({ userSelect: 'none', pointerEvents: 'none', flexShrink: 0, - fontWeight: 600 + fontWeight: 700, + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center' }} > {operand?.label ?? symbol} @@ -820,13 +870,12 @@ const FilterInput = ({ const edge = 28 let dx = 0 if (lastClientX >= rect.right - edge) { - dx = - Math.min(28, Math.ceil((lastClientX - (rect.right - edge)) / 2) + 6) - } else if (lastClientX <= rect.left + edge) { - dx = -Math.min( + dx = Math.min( 28, - Math.ceil((rect.left + edge - lastClientX) / 2) + 6 + Math.ceil((lastClientX - (rect.right - edge)) / 2) + 6 ) + } else if (lastClientX <= rect.left + edge) { + dx = -Math.min(28, Math.ceil((rect.left + edge - lastClientX) / 2) + 6) } if (dx !== 0) { @@ -865,7 +914,8 @@ const FilterInput = ({ const editor = editorRef.current if (!editor) return const selection = window.getSelection() - if (!selection?.rangeCount || !editor.contains(selection.focusNode)) return + if (!selection?.rangeCount || !editor.contains(selection.focusNode)) + return scrollSelectionIntoView(editor) } diff --git a/src/components/Icons/EqualIcon.jsx b/src/components/Icons/EqualIcon.jsx new file mode 100644 index 0000000..2962001 --- /dev/null +++ b/src/components/Icons/EqualIcon.jsx @@ -0,0 +1,6 @@ +import Icon from '@ant-design/icons' +import CustomIconSvg from '../../../assets/icons/equalicon.svg?react' + +const EqualIcon = (props) => + +export default EqualIcon diff --git a/src/components/Icons/GreaterThanIcon.jsx b/src/components/Icons/GreaterThanIcon.jsx new file mode 100644 index 0000000..b11aa95 --- /dev/null +++ b/src/components/Icons/GreaterThanIcon.jsx @@ -0,0 +1,6 @@ +import Icon from '@ant-design/icons' +import CustomIconSvg from '../../../assets/icons/greaterthanicon.svg?react' + +const GreaterThanIcon = (props) => + +export default GreaterThanIcon diff --git a/src/components/Icons/GreaterThanOrEqualToIcon.jsx b/src/components/Icons/GreaterThanOrEqualToIcon.jsx new file mode 100644 index 0000000..bd61a77 --- /dev/null +++ b/src/components/Icons/GreaterThanOrEqualToIcon.jsx @@ -0,0 +1,8 @@ +import Icon from '@ant-design/icons' +import CustomIconSvg from '../../../assets/icons/greaterthanorequaltoicon.svg?react' + +const GreaterThanOrEqualToIcon = (props) => ( + +) + +export default GreaterThanOrEqualToIcon diff --git a/src/components/Icons/LessThanIcon.jsx b/src/components/Icons/LessThanIcon.jsx new file mode 100644 index 0000000..5ec0504 --- /dev/null +++ b/src/components/Icons/LessThanIcon.jsx @@ -0,0 +1,6 @@ +import Icon from '@ant-design/icons' +import CustomIconSvg from '../../../assets/icons/lessthanicon.svg?react' + +const LessThanIcon = (props) => + +export default LessThanIcon diff --git a/src/components/Icons/LessThanOrEqualToIcon.jsx b/src/components/Icons/LessThanOrEqualToIcon.jsx new file mode 100644 index 0000000..e2ed298 --- /dev/null +++ b/src/components/Icons/LessThanOrEqualToIcon.jsx @@ -0,0 +1,8 @@ +import Icon from '@ant-design/icons' +import CustomIconSvg from '../../../assets/icons/lessthanorequaltoicon.svg?react' + +const LessThanOrEqualToIcon = (props) => ( + +) + +export default LessThanOrEqualToIcon diff --git a/src/components/Icons/NotEqualIcon.jsx b/src/components/Icons/NotEqualIcon.jsx new file mode 100644 index 0000000..82150f8 --- /dev/null +++ b/src/components/Icons/NotEqualIcon.jsx @@ -0,0 +1,6 @@ +import Icon from '@ant-design/icons' +import CustomIconSvg from '../../../assets/icons/notequalicon.svg?react' + +const NotEqualIcon = (props) => + +export default NotEqualIcon