diff --git a/src/components/BrowserFilter/BrowserFilter.react.js b/src/components/BrowserFilter/BrowserFilter.react.js index ca6fdd3379..2ec0524a33 100644 --- a/src/components/BrowserFilter/BrowserFilter.react.js +++ b/src/components/BrowserFilter/BrowserFilter.react.js @@ -491,9 +491,21 @@ export default class BrowserFilter extends React.Component { const date = new Date(compareTo.iso); return filter.set('compareTo', date); } else if (typeof compareTo === 'string' && !isNaN(Date.parse(compareTo))) { - // Convert date string to JavaScript Date - const date = new Date(compareTo); - return filter.set('compareTo', date); + // Only convert date strings to JavaScript Date if the field type is actually Date + const className = filter.get('class') || this.props.className; + const fieldName = filter.get('field'); + const schema = this.props.schema; + + if (schema && className && fieldName) { + const classSchema = schema[className]; + const fieldType = classSchema?.[fieldName]?.type; + + // Only convert to Date if the field type is actually Date + if (fieldType === 'Date') { + const date = new Date(compareTo); + return filter.set('compareTo', date); + } + } } // Leave JavaScript Date objects and other types unchanged return filter; diff --git a/src/components/BrowserFilter/FilterRow.react.js b/src/components/BrowserFilter/FilterRow.react.js index 71c0e2ef32..787cfd7f09 100644 --- a/src/components/BrowserFilter/FilterRow.react.js +++ b/src/components/BrowserFilter/FilterRow.react.js @@ -11,8 +11,10 @@ import { Constraints } from 'lib/Filters'; import DateTimeEntry from 'components/DateTimeEntry/DateTimeEntry.react'; import Icon from 'components/Icon/Icon.react'; import Parse from 'parse'; +import Popover from 'components/Popover/Popover.react'; +import Position from 'lib/Position'; import PropTypes from 'lib/PropTypes'; -import React, { useCallback } from 'react'; +import React, { useCallback, useState, useRef } from 'react'; import styles from 'components/BrowserFilter/BrowserFilter.scss'; import validateNumeric from 'lib/validateNumeric'; @@ -21,6 +23,153 @@ for (const c in Constraints) { constraintLookup[Constraints[c].name] = c; } +const RegexOptionsButton = ({ modifiers, onChangeModifiers }) => { + const [showOptions, setShowOptions] = useState(false); + const buttonRef = useRef(null); + const dropdownRef = useRef(null); + + // Parse modifiers string into individual flags + const modifiersArray = modifiers ? modifiers.split('') : []; + const hasI = modifiersArray.includes('i'); + const hasU = modifiersArray.includes('u'); + const hasM = modifiersArray.includes('m'); + const hasX = modifiersArray.includes('x'); + const hasS = modifiersArray.includes('s'); + + const toggleModifier = (modifier) => { + let newModifiers = [...modifiersArray]; + if (newModifiers.includes(modifier)) { + newModifiers = newModifiers.filter(m => m !== modifier); + } else { + newModifiers.push(modifier); + } + onChangeModifiers(newModifiers.join('')); + }; + + React.useEffect(() => { + const handleClickOutside = (event) => { + if ( + dropdownRef.current && + !dropdownRef.current.contains(event.target) && + buttonRef.current && + !buttonRef.current.contains(event.target) + ) { + setShowOptions(false); + } + }; + + if (showOptions) { + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + } + }, [showOptions]); + + const optionsDropdown = showOptions ? ( + +
+
+ Regex Options +
+ + + + + +
+
+ ) : null; + + return ( + <> + + {optionsDropdown} + + ); +}; + function compareValue( info, value, @@ -29,7 +178,9 @@ function compareValue( active, parentContentId, setFocus, - currentConstraint + currentConstraint, + modifiers, + onChangeModifiers ) { if (currentConstraint === 'containedIn') { return ( @@ -60,6 +211,21 @@ function compareValue( return null; case 'Object': case 'String': + if (currentConstraint === 'matches') { + return ( +
+ onChangeCompareTo(e.target.value)} + onKeyDown={onKeyDown} + ref={setFocus} + style={{ width: '106px' }} + /> + +
+ ); + } return ( ''} /> - Constraints[c].name)} - onChange={c => onChangeConstraint(constraintLookup[c], compareTo)} - /> +
+ Constraints[c].name)} + onChange={c => onChangeConstraint(constraintLookup[c], compareTo)} + /> +
{compareValue( compareInfo, compareTo, @@ -249,7 +419,9 @@ const FilterRow = ({ active, parentContentId, setFocus, - currentConstraint + currentConstraint, + modifiers, + onChangeModifiers )}