Enhance Filter Functionality in Dashboard Components
- Integrated property filter value into the QuickPropertyFilters component for improved filtering capabilities. - Updated ObjectTable to register page sorter and manage filter states more effectively. - Refactored QuickPropertyFilters to include category labels and clear filter functionality, enhancing user experience. - Adjusted styles and layout for better usability and visual consistency across components.
This commit is contained in:
parent
415aa0cd9d
commit
e49c7c23ed
@ -935,6 +935,7 @@ const FilterInput = ({
|
||||
<QuickPropertyFilters
|
||||
modelType={propertyFilter.modelType}
|
||||
propertyName={propertyFilter.propertyName}
|
||||
value={propertyFilterValue}
|
||||
onChange={handlePropertyFilterChange}
|
||||
onModalOpenChange={handleQuickFilterModalOpenChange}
|
||||
useCard={false}
|
||||
|
||||
@ -38,7 +38,6 @@ import ObjectProperty from './ObjectProperty'
|
||||
import ObjectCard from './ObjectCard'
|
||||
import FilterSidebar from './FilterSidebar'
|
||||
import SortSidebar from './SortSidebar'
|
||||
import XMarkIcon from '../../Icons/XMarkIcon'
|
||||
import CheckIcon from '../../Icons/CheckIcon'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import QuestionCircleIcon from '../../Icons/QuestionCircleIcon'
|
||||
@ -139,13 +138,6 @@ const ColumnFilterDropdown = ({
|
||||
confirm()
|
||||
}
|
||||
|
||||
const resetFilter = () => {
|
||||
setExpression('')
|
||||
setDraft([])
|
||||
clearFilters()
|
||||
confirm()
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ padding: 8 }}>
|
||||
<Flex vertical gap='small'>
|
||||
@ -155,14 +147,14 @@ const ColumnFilterDropdown = ({
|
||||
value={expression}
|
||||
onChange={handleExpressionChange}
|
||||
onPressEnter={applyFilter}
|
||||
style={{ width: 200 }}
|
||||
style={{ width: 260 }}
|
||||
/>
|
||||
<Button onClick={resetFilter} icon={<XMarkIcon />} />
|
||||
<Button type='primary' onClick={applyFilter} icon={<CheckIcon />} />
|
||||
</Space.Compact>
|
||||
<QuickPropertyFilters
|
||||
modelType={modelType}
|
||||
propertyName={propertyName}
|
||||
value={draft}
|
||||
onChange={handleDraftChange}
|
||||
/>
|
||||
<Card size='small' styles={{ body: { padding: 0, height: 200 } }}>
|
||||
@ -291,7 +283,8 @@ const ObjectTable = forwardRef(
|
||||
persistFilter,
|
||||
persistSort,
|
||||
persistTableState,
|
||||
registerPageFilter
|
||||
registerPageFilter,
|
||||
registerPageSorter
|
||||
} = useTableStatePersistence({
|
||||
scope: type,
|
||||
pagePath: location.pathname,
|
||||
@ -1116,6 +1109,11 @@ const ObjectTable = forwardRef(
|
||||
return () => registerPageFilter({})
|
||||
}, [sidebarFilter, registerPageFilter])
|
||||
|
||||
useEffect(() => {
|
||||
registerPageSorter(tableSorter)
|
||||
return () => registerPageSorter({})
|
||||
}, [tableSorter, registerPageSorter])
|
||||
|
||||
const getFilterDropdown = ({
|
||||
setSelectedKeys,
|
||||
selectedKeys,
|
||||
|
||||
@ -4,6 +4,7 @@ import {
|
||||
Card,
|
||||
DatePicker,
|
||||
Descriptions,
|
||||
Dropdown,
|
||||
Flex,
|
||||
Input,
|
||||
Modal,
|
||||
@ -18,6 +19,7 @@ import {
|
||||
getModelProperties
|
||||
} from '../../../database/ObjectModels'
|
||||
import { isDateTimePropertyType } from './filterExpression'
|
||||
import { CaretRightFilled } from '@ant-design/icons'
|
||||
|
||||
const { Text } = Typography
|
||||
|
||||
@ -135,6 +137,22 @@ const getPropertyCategory = (property) => {
|
||||
return 'text'
|
||||
}
|
||||
|
||||
const getCategoryLabel = (category) => {
|
||||
switch (category) {
|
||||
case 'boolean':
|
||||
return 'Boolean'
|
||||
case 'number':
|
||||
return 'Number'
|
||||
case 'date':
|
||||
return 'Date'
|
||||
case 'object':
|
||||
return 'Object'
|
||||
case 'text':
|
||||
default:
|
||||
return 'Text'
|
||||
}
|
||||
}
|
||||
|
||||
const getFilterOptions = (category) => {
|
||||
switch (category) {
|
||||
case 'boolean':
|
||||
@ -146,6 +164,7 @@ const getFilterOptions = (category) => {
|
||||
return [
|
||||
{ key: 'equals', label: 'Equals', needsValue: true },
|
||||
{ key: 'notEquals', label: 'Does not equal', needsValue: true },
|
||||
{ type: 'divider' },
|
||||
{ key: 'greaterThan', label: 'Greater than', needsValue: true },
|
||||
{
|
||||
key: 'greaterOrEqual',
|
||||
@ -158,13 +177,16 @@ const getFilterOptions = (category) => {
|
||||
label: 'Less than or equal',
|
||||
needsValue: true
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{ key: 'between', label: 'Between', needsRange: true }
|
||||
]
|
||||
case 'date':
|
||||
return [
|
||||
{ key: 'equals', label: 'On', needsValue: true },
|
||||
{ type: 'divider' },
|
||||
{ key: 'lessThan', label: 'Before', needsValue: true },
|
||||
{ key: 'greaterThan', label: 'After', needsValue: true },
|
||||
{ type: 'divider' },
|
||||
{ key: 'between', label: 'Between', needsRange: true }
|
||||
]
|
||||
case 'object':
|
||||
@ -181,20 +203,36 @@ const getFilterOptions = (category) => {
|
||||
label: 'Does not start with',
|
||||
needsValue: true
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{ key: 'contains', label: 'Contains', needsValue: true },
|
||||
{ key: 'notContains', label: 'Does not contain', needsValue: true },
|
||||
{ type: 'divider' },
|
||||
{ key: 'endsWith', label: 'Ends with', needsValue: true },
|
||||
{ key: 'notEndsWith', label: 'Does not end with', needsValue: true },
|
||||
{ type: 'divider' },
|
||||
{ key: 'equals', label: 'Equals', needsValue: true },
|
||||
{ key: 'notEquals', label: 'Does not equal', needsValue: true },
|
||||
{ type: 'divider' },
|
||||
{ key: 'isEmpty', label: 'Is empty' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
const buildFilterMenuItems = (options, onOptionClick) =>
|
||||
options.map((item) =>
|
||||
item.type === 'divider'
|
||||
? item
|
||||
: {
|
||||
key: item.key,
|
||||
label: item.label,
|
||||
onClick: () => onOptionClick(item)
|
||||
}
|
||||
)
|
||||
|
||||
const QuickPropertyFilters = ({
|
||||
modelType,
|
||||
propertyName,
|
||||
value = [],
|
||||
onChange,
|
||||
onModalOpenChange,
|
||||
useCard = true
|
||||
@ -216,6 +254,11 @@ const QuickPropertyFilters = ({
|
||||
const options = useMemo(() => getFilterOptions(category), [category])
|
||||
|
||||
const propertyLabel = property?.label || propertyName
|
||||
const categoryLabel = getCategoryLabel(category)
|
||||
|
||||
const handleClear = () => {
|
||||
onChange?.([])
|
||||
}
|
||||
|
||||
const closeModal = () => {
|
||||
onModalOpenChange?.(false)
|
||||
@ -317,25 +360,41 @@ const QuickPropertyFilters = ({
|
||||
)
|
||||
}
|
||||
|
||||
const filterMenuItems = buildFilterMenuItems(options, handleOptionClick)
|
||||
|
||||
if (!property) return null
|
||||
|
||||
const content = (
|
||||
<Flex vertical gap={0}>
|
||||
{options.map((option) => (
|
||||
<Flex gap={0} vertical>
|
||||
<Button
|
||||
disabled={!value?.length}
|
||||
onClick={handleClear}
|
||||
style={{
|
||||
textAlign: 'left',
|
||||
padding: '5px 12px',
|
||||
justifyContent: 'flex-start'
|
||||
}}
|
||||
type='text'
|
||||
>
|
||||
Clear Filter from "{propertyLabel}"
|
||||
</Button>
|
||||
<Dropdown
|
||||
menu={{ items: filterMenuItems }}
|
||||
trigger={['hover']}
|
||||
placement='rightTop'
|
||||
>
|
||||
<Button
|
||||
key={option.key}
|
||||
type='text'
|
||||
block
|
||||
style={{
|
||||
justifyContent: 'flex-start',
|
||||
textAlign: 'left',
|
||||
padding: '5px 12px'
|
||||
padding: '5px 12px',
|
||||
justifyContent: 'flex-start'
|
||||
}}
|
||||
onClick={() => handleOptionClick(option)}
|
||||
type='text'
|
||||
>
|
||||
{option.label}
|
||||
{categoryLabel} Filters
|
||||
{<CaretRightFilled style={{ marginLeft: 'auto' }} />}
|
||||
</Button>
|
||||
))}
|
||||
</Dropdown>
|
||||
</Flex>
|
||||
)
|
||||
|
||||
@ -376,7 +435,7 @@ const QuickPropertyFilters = ({
|
||||
<Text>
|
||||
{activeOption.needsRange
|
||||
? `Enter a range to continue:`
|
||||
: `Enter a value to continue:`}
|
||||
: `Enter a ${categoryLabel.toLowerCase()} value to continue:`}
|
||||
</Text>
|
||||
{activeOption.needsRange ? (
|
||||
<Flex vertical gap='middle'>
|
||||
@ -435,6 +494,7 @@ const QuickPropertyFilters = ({
|
||||
QuickPropertyFilters.propTypes = {
|
||||
modelType: PropTypes.string,
|
||||
propertyName: PropTypes.string,
|
||||
value: PropTypes.array,
|
||||
onChange: PropTypes.func,
|
||||
onModalOpenChange: PropTypes.func,
|
||||
useCard: PropTypes.bool
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user