Skip to content

New points filers design#344

Merged
generall merged 29 commits intomasterfrom
new-filers
Jan 23, 2026
Merged

New points filers design#344
generall merged 29 commits intomasterfrom
new-filers

Conversation

@trean
Copy link
Copy Markdown
Contributor

@trean trean commented Jan 21, 2026

image

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request redesigns the points filtering interface with a new two-field layout featuring syntax highlighting, autocomplete functionality, and skeleton loading states. The old SimilarSerachfield component is replaced with a modern filter system that separates similar search and payload filtering into distinct, interactive components.

Changes:

  • Introduced new filter components (PointsFilter, SimilarSearchField, PayloadFilterField) with autocomplete and syntax highlighting
  • Added PointCardSkeleton component for better loading UX with skeleton screens
  • Refactored loading state management using requestCount to handle concurrent requests

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/components/Points/PointsTabs.jsx Updated to use new PointsFilter component, added requestCount-based loading state, and integrated skeleton loading
src/components/Points/PointsFilter/PointsFilter.jsx New main filter container that coordinates similar search and payload filter fields with responsive layout
src/components/Points/PointsFilter/SimilarSearchField.jsx New component for similar search with chip-based UI, auto-expand behavior, and Autocomplete integration
src/components/Points/PointsFilter/PayloadFilterField.jsx New payload filter with syntax highlighting, autocomplete suggestions, and keyboard navigation
src/components/Points/PointsFilter/StyledPointsFilter.js Styled components and shared styling utilities for the filter components
src/components/Points/PointsFilter/helpers.js Utility functions for parsing, normalizing, and processing filter inputs
src/components/Points/PointCardSkeleton.jsx New skeleton loading component for point cards
package-lock.json Dependency updates including version changes to MUI packages and other dependencies

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

))}
</>
)}
{points && !errorMessage && requestCount === 0 && points.points?.length === 0 && (
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition check on line 176 evaluates requestCount === 0 along with other conditions. However, this might create a race condition where points become available but requestCount is still > 0 briefly, causing the "No Points" message not to appear when it should. Consider whether the requestCount check is necessary here or if it should be part of the isLoading check instead.

Suggested change
{points && !errorMessage && requestCount === 0 && points.points?.length === 0 && (
{!isLoading && points && !errorMessage && points.points?.length === 0 && (

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +35
import React from 'react';
import { Card, CardContent, CardHeader, Divider, Skeleton, Box } from '@mui/material';

const PointCardSkeleton = () => {
return (
<Card
elevation={0}
sx={{
display: 'flex',
flexDirection: 'column',
height: '100%',
}}
>
<CardHeader
title={<Skeleton variant="text" width="60%" height={24} />}
action={
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Skeleton variant="circular" width={32} height={32} sx={{ mr: 1 }} />
<Skeleton variant="circular" width={32} height={32} />
</Box>
}
/>
<CardContent sx={{ padding: '0.5rem 1rem' }}>
<Skeleton variant="rounded" height={60} sx={{ mb: 1 }} />
<Skeleton variant="rounded" height={40} />
</CardContent>
<Divider />
<CardContent sx={{ padding: '1rem' }}>
<Skeleton variant="rounded" height={100} />
</CardContent>
</Card>
);
};

export default PointCardSkeleton;
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new PointCardSkeleton component lacks test coverage. Given that the repository has comprehensive test coverage for other components, this new component should include unit tests to ensure it renders correctly and handles its props appropriately.

Copilot uses AI. Check for mistakes.
Comment on lines +170 to +185
export const calculatePopperOffset = (filterInputValue, currentWordStart) => {
// Get the text before the current word
const textBeforeWord = filterInputValue.slice(0, currentWordStart);

// Measure the width of text before the word using a canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Match the editor's font
ctx.font = '1rem system-ui, -apple-system, sans-serif';
const textWidth = ctx.measureText(textBeforeWord).width;

// Add offset for the filter icon (approximately 24px for icon + margin)
const iconOffset = 28;

return [textWidth + iconOffset, 4];
};
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The calculatePopperOffset function creates a new canvas element on every call but never cleans it up. This could lead to memory leaks if the function is called frequently. Consider caching the canvas element or using a more efficient method to measure text width, such as using a hidden DOM element with the same font styling.

Copilot uses AI. Check for mistakes.
onExpandChange(false);
} else if (conditionLabels.length > MAX_VISIBLE_CHIPS) {
onExpandChange(true);
} else if (conditionLabels.length <= MAX_VISIBLE_CHIPS) {
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The auto-expand/collapse logic has redundant conditions. Lines 53-57 check both > MAX_VISIBLE_CHIPS and <= MAX_VISIBLE_CHIPS, with the second condition being unnecessary since it's the else case. Simplify by removing the else-if condition on line 55 and just using an else block.

Suggested change
} else if (conditionLabels.length <= MAX_VISIBLE_CHIPS) {
} else {

Copilot uses AI. Check for mistakes.
const handleValueChange = useCallback((newValue) => {
setInputValue(newValue);
setHighlightedIndex(0);
setCursorPosition(newValue.length);
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handleValueChange function always sets cursorPosition to newValue.length, which means the cursor position is always placed at the end of the input when the value changes. This could be incorrect if the user is typing in the middle of the text. Consider tracking the actual cursor position from the textarea's selectionStart instead of assuming it's at the end.

Suggested change
setCursorPosition(newValue.length);
// Derive cursor position from the underlying textarea's selectionStart when possible
setTimeout(() => {
const textarea = containerRef.current?.querySelector('textarea');
if (textarea && typeof textarea.selectionStart === 'number') {
setCursorPosition(textarea.selectionStart);
} else {
// Fallback to placing cursor at the end if selectionStart is unavailable
setCursorPosition(newValue.length);
}
}, 0);

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +65
import React, { useMemo, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { Box, Grid } from '@mui/material';

import SimilarSearchField from './SimilarSearchField';
import PayloadFilterField from './PayloadFilterField';

const PointsFilter = ({ onConditionChange, conditions = [], payloadSchema = {}, points }) => {
const [isSimilarExpanded, setIsSimilarExpanded] = useState(false);

const similarConditions = useMemo(() => conditions.filter((condition) => condition.type === 'id'), [conditions]);

const payloadConditions = useMemo(() => conditions.filter((condition) => condition.type === 'payload'), [conditions]);

const payloadKeyOptions = useMemo(() => {
const keys = new Set();
Object.keys(points?.payload_schema || {}).forEach((key) => keys.add(key));
Object.keys(payloadSchema || {}).forEach((key) => keys.add(key));
return [...keys];
}, [points, payloadSchema]);

const handleExpandChange = useCallback((expanded) => {
setIsSimilarExpanded(expanded);
}, []);

return (
<Box>
<Grid container spacing={1}>
{/* Similar search field (with chips) */}
<Grid size={{ xs: 12, md: isSimilarExpanded ? 12 : 3 }}>
<SimilarSearchField
similarConditions={similarConditions}
payloadConditions={payloadConditions}
onConditionChange={onConditionChange}
isExpanded={isSimilarExpanded}
onExpandChange={handleExpandChange}
/>
</Grid>

{/* Payload filter field (with syntax highlighting) */}
<Grid size={{ xs: 12, md: isSimilarExpanded ? 12 : 9 }}>
<PayloadFilterField
payloadConditions={payloadConditions}
similarConditions={similarConditions}
payloadSchema={payloadSchema}
payloadKeyOptions={payloadKeyOptions}
onConditionChange={onConditionChange}
/>
</Grid>
</Grid>
</Box>
);
};

PointsFilter.propTypes = {
conditions: PropTypes.array,
payloadSchema: PropTypes.object,
points: PropTypes.shape({
payload_schema: PropTypes.object,
points: PropTypes.arrayOf(PropTypes.shape({ payload: PropTypes.object })),
}),
onConditionChange: PropTypes.func.isRequired,
};

export default PointsFilter;
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new PointsFilter components (PointsFilter.jsx, SimilarSearchField.jsx, PayloadFilterField.jsx) and helper functions (helpers.js) lack test coverage. Given that the repository has comprehensive test coverage for other components (e.g., CollectionAliases, ClusterShardRow, CreateCollection), these new components should also include unit tests to ensure their functionality is properly validated.

Copilot uses AI. Check for mistakes.
@generall generall marked this pull request as ready for review January 23, 2026 20:11
@generall generall merged commit 09c9003 into master Jan 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants