Add new comparison icons and update FilterInput with operand icons
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
- Introduced new SVG icons for comparison operators: Equal, Greater Than, Greater Than or Equal To, Less Than, Less Than or Equal To, and Not Equal. - Updated FilterInput component to utilize these new icons for better visual representation of operand symbols. - Enhanced the layout and styling of operand labels within the FilterInput for improved user experience.
This commit is contained in:
parent
a483fd91ca
commit
fc2dbbd14d
7
assets/icons/equalicon.svg
Normal file
7
assets/icons/equalicon.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g transform="matrix(1.245638,0,0,1.245638,3,12.546644)">
|
||||||
|
<path d="M4.656,9.516L41.906,9.516C44.391,9.516 46.562,7.359 46.562,4.781C46.562,2.203 44.391,0.047 41.906,0.047L4.656,0.047C2.266,0.047 0,2.203 0,4.781C0,7.359 2.266,9.516 4.656,9.516ZM4.656,31.188L41.906,31.188C44.391,31.188 46.562,29.047 46.562,26.469C46.562,23.891 44.391,21.719 41.906,21.719L4.656,21.719C2.266,21.719 0,23.891 0,26.469C0,29.047 2.266,31.188 4.656,31.188Z" style="fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 936 B |
7
assets/icons/greaterthanicon.svg
Normal file
7
assets/icons/greaterthanicon.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g transform="matrix(-1.243968,0,0,1.243968,61,3.835791)">
|
||||||
|
<path d="M42.109,45.25C44.844,45.25 46.625,43.016 46.625,40.172C46.625,37.656 45.609,36.141 42.891,35.062L13.141,22.688L13.141,22.297L42.875,9.891C45.422,8.859 46.625,7.391 46.625,4.984C46.625,2.156 44.656,0.031 41.844,0.031C40.516,0.031 39.406,0.359 38.281,0.906L5.203,15.984C1.922,17.453 0,19.469 0,22.688C0,25.938 1.922,27.969 5.203,29.453L38.281,44.281C39.5,44.828 40.688,45.25 42.109,45.25Z" style="fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 956 B |
7
assets/icons/greaterthanorequaltoicon.svg
Normal file
7
assets/icons/greaterthanorequaltoicon.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g transform="matrix(1.039523,0,0,1.039523,10.860319,2)">
|
||||||
|
<path d="M0,52.969C0,55.75 1.984,57.719 4.734,57.719L35.953,57.719C38.688,57.719 40.672,55.75 40.672,52.969C40.672,50.219 38.688,48.25 35.953,48.25L4.734,48.25C1.984,48.25 0,50.219 0,52.969ZM4.531,40.031C1.766,40.031 0,37.797 0,34.953C0,32.453 1.094,30.984 3.734,29.906L26.438,19.969L26.438,19.625L3.75,9.844C1.266,8.828 0,7.359 0,4.953C0,2.125 1.969,0 4.797,0C6.109,0 7.297,0.328 8.344,0.859L34.375,13.328C37.609,14.891 39.578,16.766 39.578,19.984C39.578,23.25 37.625,25.125 34.375,26.703L8.344,39.094C7.188,39.672 5.938,40.031 4.531,40.031Z" style="fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
7
assets/icons/lessthanicon.svg
Normal file
7
assets/icons/lessthanicon.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g transform="matrix(1.243968,0,0,1.243968,3,3.835791)">
|
||||||
|
<path d="M42.109,45.25C44.844,45.25 46.625,43.016 46.625,40.172C46.625,37.656 45.609,36.141 42.891,35.062L13.141,22.688L13.141,22.297L42.875,9.891C45.422,8.859 46.625,7.391 46.625,4.984C46.625,2.156 44.656,0.031 41.844,0.031C40.516,0.031 39.406,0.359 38.281,0.906L5.203,15.984C1.922,17.453 0,19.469 0,22.688C0,25.938 1.922,27.969 5.203,29.453L38.281,44.281C39.5,44.828 40.688,45.25 42.109,45.25Z" style="fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 954 B |
7
assets/icons/lessthanorequaltoicon.svg
Normal file
7
assets/icons/lessthanorequaltoicon.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g transform="matrix(1.039523,0,0,1.039523,10.860319,2)">
|
||||||
|
<path d="M0,52.969C0,55.75 1.984,57.719 4.734,57.719L35.953,57.719C38.688,57.719 40.672,55.75 40.672,52.969C40.672,50.219 38.688,48.25 35.953,48.25L4.734,48.25C1.984,48.25 0,50.219 0,52.969ZM35.047,40.031C37.812,40.031 39.578,37.797 39.578,34.953C39.578,32.453 38.484,30.984 35.844,29.906L13.141,19.969L13.141,19.625L35.828,9.844C38.312,8.828 39.578,7.359 39.578,4.953C39.578,2.125 37.609,0 34.781,0C33.469,0 32.281,0.328 31.234,0.859L5.203,13.328C1.969,14.891 0,16.766 0,19.984C0,23.25 1.953,25.125 5.203,26.703L31.234,39.094C32.391,39.672 33.641,40.031 35.047,40.031Z" style="fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
10
assets/icons/notequalicon.svg
Normal file
10
assets/icons/notequalicon.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g transform="matrix(1.245638,0,0,1.245638,3,12.546644)">
|
||||||
|
<path d="M4.656,9.516L41.906,9.516C44.391,9.516 46.562,7.359 46.562,4.781C46.562,2.203 44.391,0.047 41.906,0.047L4.656,0.047C2.266,0.047 0,2.203 0,4.781C0,7.359 2.266,9.516 4.656,9.516ZM4.656,31.188L41.906,31.188C44.391,31.188 46.562,29.047 46.562,26.469C46.562,23.891 44.391,21.719 41.906,21.719L4.656,21.719C2.266,21.719 0,23.891 0,26.469C0,29.047 2.266,31.188 4.656,31.188Z" style="fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(1.245638,0,0,1.245638,3,-1.178629)">
|
||||||
|
<path d="M7.547,51.55C9.859,52.878 12.578,52.097 13.875,49.769L40.688,8.027C41.984,5.73 41.281,3.121 38.969,1.824C36.641,0.496 34.094,1.152 32.656,3.636L6,45.206C4.641,47.612 5.188,50.237 7.547,51.55ZM4.656,20.579L41.906,20.579C44.391,20.579 46.562,18.423 46.562,15.845C46.562,13.266 44.391,11.11 41.906,11.11L4.656,11.11C2.266,11.11 0,13.266 0,15.845C0,18.423 2.266,20.579 4.656,20.579ZM4.656,42.251L41.906,42.251C44.391,42.251 46.562,40.11 46.562,37.532C46.562,34.954 44.391,32.782 41.906,32.782L4.656,32.782C2.266,32.782 0,34.954 0,37.532C0,40.11 2.266,42.251 4.656,42.251Z" style="fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
@ -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 { ConfigProvider, Popover, Tag, theme } from 'antd'
|
||||||
import { CloseCircleFilled } from '@ant-design/icons'
|
import { CloseCircleFilled } from '@ant-design/icons'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
@ -11,19 +18,58 @@ import useStyle, { useSharedStyle } from 'antd/es/input/style'
|
|||||||
import { useThemeContext } from '../context/ThemeContext'
|
import { useThemeContext } from '../context/ThemeContext'
|
||||||
import SimplePropertyFilter from './SimplePropertyFilter'
|
import SimplePropertyFilter from './SimplePropertyFilter'
|
||||||
import ScrollBox from './ScrollBox'
|
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 "." / "<" / ">".
|
// Longer symbols first so ".." / "<>" / ">=" match before "." / "<" / ">".
|
||||||
// Wildcards (* ?) and @ stay as plain text — they are not operands.
|
// Wildcards (* ?) and @ stay as plain text — they are not operands.
|
||||||
const OPERANDS = [
|
const OPERANDS = [
|
||||||
{ symbol: '..', label: 'TO', color: 'cyan' },
|
{
|
||||||
{ symbol: '<>', label: '≠', color: 'volcano' },
|
symbol: '..',
|
||||||
{ symbol: '>=', label: '> OR =', color: 'orange' },
|
label: <ArrowLeftIcon style={operandIconStyle} />,
|
||||||
{ symbol: '<=', label: '< OR =', color: 'orange' },
|
color: 'cyan'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: '<>',
|
||||||
|
label: <NotEqualIcon style={operandIconStyle} />,
|
||||||
|
color: 'volcano'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: '>=',
|
||||||
|
label: <GreaterThanOrEqualToIcon style={operandIconStyle} />,
|
||||||
|
color: 'orange'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: '<=',
|
||||||
|
label: <LessThanOrEqualToIcon style={operandIconStyle} />,
|
||||||
|
color: 'orange'
|
||||||
|
},
|
||||||
{ symbol: '|', label: 'OR', color: 'purple' },
|
{ symbol: '|', label: 'OR', color: 'purple' },
|
||||||
{ symbol: '&', label: 'AND', color: 'purple' },
|
{ symbol: '&', label: 'AND', color: 'purple' },
|
||||||
{ symbol: '>', label: '>', color: 'orange' },
|
{
|
||||||
{ symbol: '<', label: '<', color: 'orange' },
|
symbol: '>',
|
||||||
{ symbol: '=', label: '=', color: 'blue' }
|
label: (
|
||||||
|
<GreaterThanIcon style={{ ...operandIconStyle, marginLeft: '1px' }} />
|
||||||
|
),
|
||||||
|
color: 'orange'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: '<',
|
||||||
|
label: <LessThanIcon style={{ ...operandIconStyle, marginRight: '1px' }} />,
|
||||||
|
color: 'orange'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: '=',
|
||||||
|
label: <EqualIcon style={operandIconStyle} />,
|
||||||
|
color: 'blue'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const OPERAND_BY_SYMBOL = Object.fromEntries(
|
const OPERAND_BY_SYMBOL = Object.fromEntries(
|
||||||
@ -101,7 +147,8 @@ const getOffsetAt = (root, targetNode, targetOffset, chipSnap = 'end') => {
|
|||||||
if (node.nodeType === Node.TEXT_NODE) {
|
if (node.nodeType === Node.TEXT_NODE) {
|
||||||
offset += targetOffset
|
offset += targetOffset
|
||||||
} else if (node.getAttribute?.('data-operand') != null) {
|
} 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 {
|
} else {
|
||||||
for (let i = 0; i < targetOffset; i += 1) {
|
for (let i = 0; i < targetOffset; i += 1) {
|
||||||
offset += nodeLength(node.childNodes[i])
|
offset += nodeLength(node.childNodes[i])
|
||||||
@ -421,7 +468,10 @@ const FilterInput = ({
|
|||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
fontWeight: 600
|
fontWeight: 700,
|
||||||
|
display: 'inline-flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{operand?.label ?? symbol}
|
{operand?.label ?? symbol}
|
||||||
@ -820,13 +870,12 @@ const FilterInput = ({
|
|||||||
const edge = 28
|
const edge = 28
|
||||||
let dx = 0
|
let dx = 0
|
||||||
if (lastClientX >= rect.right - edge) {
|
if (lastClientX >= rect.right - edge) {
|
||||||
dx =
|
dx = Math.min(
|
||||||
Math.min(28, Math.ceil((lastClientX - (rect.right - edge)) / 2) + 6)
|
|
||||||
} else if (lastClientX <= rect.left + edge) {
|
|
||||||
dx = -Math.min(
|
|
||||||
28,
|
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) {
|
if (dx !== 0) {
|
||||||
@ -865,7 +914,8 @@ const FilterInput = ({
|
|||||||
const editor = editorRef.current
|
const editor = editorRef.current
|
||||||
if (!editor) return
|
if (!editor) return
|
||||||
const selection = window.getSelection()
|
const selection = window.getSelection()
|
||||||
if (!selection?.rangeCount || !editor.contains(selection.focusNode)) return
|
if (!selection?.rangeCount || !editor.contains(selection.focusNode))
|
||||||
|
return
|
||||||
scrollSelectionIntoView(editor)
|
scrollSelectionIntoView(editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
src/components/Icons/EqualIcon.jsx
Normal file
6
src/components/Icons/EqualIcon.jsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import Icon from '@ant-design/icons'
|
||||||
|
import CustomIconSvg from '../../../assets/icons/equalicon.svg?react'
|
||||||
|
|
||||||
|
const EqualIcon = (props) => <Icon component={CustomIconSvg} {...props} />
|
||||||
|
|
||||||
|
export default EqualIcon
|
||||||
6
src/components/Icons/GreaterThanIcon.jsx
Normal file
6
src/components/Icons/GreaterThanIcon.jsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import Icon from '@ant-design/icons'
|
||||||
|
import CustomIconSvg from '../../../assets/icons/greaterthanicon.svg?react'
|
||||||
|
|
||||||
|
const GreaterThanIcon = (props) => <Icon component={CustomIconSvg} {...props} />
|
||||||
|
|
||||||
|
export default GreaterThanIcon
|
||||||
8
src/components/Icons/GreaterThanOrEqualToIcon.jsx
Normal file
8
src/components/Icons/GreaterThanOrEqualToIcon.jsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import Icon from '@ant-design/icons'
|
||||||
|
import CustomIconSvg from '../../../assets/icons/greaterthanorequaltoicon.svg?react'
|
||||||
|
|
||||||
|
const GreaterThanOrEqualToIcon = (props) => (
|
||||||
|
<Icon component={CustomIconSvg} {...props} />
|
||||||
|
)
|
||||||
|
|
||||||
|
export default GreaterThanOrEqualToIcon
|
||||||
6
src/components/Icons/LessThanIcon.jsx
Normal file
6
src/components/Icons/LessThanIcon.jsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import Icon from '@ant-design/icons'
|
||||||
|
import CustomIconSvg from '../../../assets/icons/lessthanicon.svg?react'
|
||||||
|
|
||||||
|
const LessThanIcon = (props) => <Icon component={CustomIconSvg} {...props} />
|
||||||
|
|
||||||
|
export default LessThanIcon
|
||||||
8
src/components/Icons/LessThanOrEqualToIcon.jsx
Normal file
8
src/components/Icons/LessThanOrEqualToIcon.jsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import Icon from '@ant-design/icons'
|
||||||
|
import CustomIconSvg from '../../../assets/icons/lessthanorequaltoicon.svg?react'
|
||||||
|
|
||||||
|
const LessThanOrEqualToIcon = (props) => (
|
||||||
|
<Icon component={CustomIconSvg} {...props} />
|
||||||
|
)
|
||||||
|
|
||||||
|
export default LessThanOrEqualToIcon
|
||||||
6
src/components/Icons/NotEqualIcon.jsx
Normal file
6
src/components/Icons/NotEqualIcon.jsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import Icon from '@ant-design/icons'
|
||||||
|
import CustomIconSvg from '../../../assets/icons/notequalicon.svg?react'
|
||||||
|
|
||||||
|
const NotEqualIcon = (props) => <Icon component={CustomIconSvg} {...props} />
|
||||||
|
|
||||||
|
export default NotEqualIcon
|
||||||
Loading…
x
Reference in New Issue
Block a user