Skip to content

Commit

Permalink
Find similar by ID or filter by payload key:value pair. (#167)
Browse files Browse the repository at this point in the history
* Add payload filter in view point page.

* Refactor Collection component to improve code readability and remove unused state variables

* Refactor PointCard, PointVectors, and SimilarSearchfield components

* Update placeholder text in SimilarSerachfield component

* Fix duplicate condition check in DataGridList and SimilarSerachfield components

* Add filter button to DataGridList component

* Add handleDeleteAllChips function to SimilarSerachfield component

* Refactor Collection component

* Refactor DataGridList component and add payloadSchema prop

* Refactor SimilarSearchfield component parse a string into primitive values in chip input

* Add filter based indexed fields

* Refactor PointsTabs and SimilarSerachfield components

* Fix condition check in PointsTabs and add error handling in SimilarSerachfield

* disableEdition SimilarSearchfield component
  • Loading branch information
kartik-gupta-ij authored Mar 19, 2024
1 parent c710f9f commit 6afc89f
Show file tree
Hide file tree
Showing 7 changed files with 384 additions and 177 deletions.
7 changes: 7 additions & 0 deletions src/common/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,10 @@ export const updateProgress = function (snapshotSize, callback) {
callback(newProgress);
};
};

const uuidRegex =
/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;

export const validateUuid = function (uuid) {
return typeof uuid === 'string' && uuidRegex.test(uuid);
};
72 changes: 52 additions & 20 deletions src/components/Points/DataGridList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ import React from 'react';
import PropTypes from 'prop-types';
import { JsonViewer } from '@textea/json-viewer';
import { useTheme } from '@mui/material/styles';
import { Divider, Grid, Typography } from '@mui/material';
import { Divider, Grid, IconButton, Typography } from '@mui/material';
import FilterAltIcon from '@mui/icons-material/FilterAlt';

/**
* A list of key-value pairs, where the value is either a string or an object.
* if the value is an object, it will be rendered as a JSON tree.
* @param {Object} data - key-value pairs to render
* @param {Object} specialCases - key-value pairs to render, where the value is JSX element
* @param {Function} onConditionChange - callback for changing conditions
* @param {Array} conditions - current conditions
* @return {unknown[]} - array of JSX elements
*/
export const DataGridList = function ({ data = {}, specialCases = {} }) {
export const DataGridList = function ({ data = {}, specialCases = {}, onConditionChange, conditions, payloadSchema }) {
const theme = useTheme();
const specialKeys = Object.keys(specialCases) || [];

Expand All @@ -36,31 +39,57 @@ export const DataGridList = function ({ data = {}, specialCases = {} }) {
{/* special cases */}
{specialKeys?.includes(key) && specialCases[key]}

{/* objects */}
{typeof data[key] === 'object' && !specialKeys.includes(key) && (
<Typography variant="subtitle1">
{' '}
<Typography
variant="subtitle1"
color="text.secondary"
sx={{
wordBreak: 'break-word',
width: '100%',
display: 'inline-flex',
justifyContent: 'space-between',
}}
>
{/* objects */}
{typeof data[key] === 'object' && !specialKeys.includes(key) && (
<JsonViewer
theme={theme.palette.mode}
value={data[key]}
displayDataTypes={false}
defaultInspectDepth={0}
rootName={false}
/>{' '}
</Typography>
)}
/>
)}

{/* other types of values */}
{typeof data[key] !== 'object' && !specialKeys.includes(key) && (
<Typography
variant="subtitle1"
color="text.secondary"
display={'inline'}
sx={{ wordBreak: 'break-word' }}
>
{'\t'} {data[key].toString()}
</Typography>
)}
{/* other types of values */}
{typeof data[key] !== 'object' && !specialKeys.includes(key) && (
<span>
{'\t'} {data[key].toString()}
</span>
)}
{payloadSchema &&
payloadSchema[key] &&
(payloadSchema[key].data_type === 'keyword' ||
payloadSchema[key].data_type === 'text' ||
payloadSchema[key].data_type === 'integer' ||
payloadSchema[key].data_type === 'bool') && (
<IconButton
size="small"
onClick={() => {
const filter = {
key: key,
type: 'payload',
value: data[key],
};
if (conditions.find((c) => c.key === filter.key && c.value === filter.value)) {
return;
}
onConditionChange([...conditions, filter]);
}}
>
<FilterAltIcon />
</IconButton>
)}
</Typography>
</Grid>
</Grid>
<Divider />
Expand All @@ -80,4 +109,7 @@ DataGridList.propTypes = {
key: PropTypes.string,
value: PropTypes.element,
}),
onConditionChange: PropTypes.func,
conditions: PropTypes.array,
payloadSchema: PropTypes.object,
};
17 changes: 11 additions & 6 deletions src/components/Points/PointCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { bigIntJSON } from '../../common/bigIntJSON';

const PointCard = (props) => {
const theme = useTheme();
const { setRecommendationIds } = props;
const { onConditionChange, conditions } = props;
const [point, setPoint] = React.useState(props.point);
const [openPayloadEditor, setOpenPayloadEditor] = React.useState(false);
const [loading, setLoading] = React.useState(false);
Expand Down Expand Up @@ -118,7 +118,12 @@ const PointCard = (props) => {
<CardContent>
<Grid container display={'flex'}>
<Grid item xs my={1}>
<DataGridList data={point.payload} />
<DataGridList
data={point.payload}
onConditionChange={onConditionChange}
conditions={conditions}
payloadSchema={props.payloadSchema}
/>
</Grid>
{point.payload && <PointImage data={point.payload} sx={{ ml: 2 }} />}
</Grid>
Expand All @@ -132,9 +137,7 @@ const PointCard = (props) => {
background: alpha(theme.palette.primary.main, 0.05),
}}
/>
<CardContent>
{point?.vector && <Vectors point={point} setRecommendationIds={setRecommendationIds} />}
</CardContent>
<CardContent>{point?.vector && <Vectors point={point} onConditionChange={onConditionChange} />}</CardContent>
</Card>
<PayloadEditor
collectionName={props.collectionName}
Expand All @@ -161,9 +164,11 @@ const PointCard = (props) => {

PointCard.propTypes = {
point: PropTypes.object.isRequired,
setRecommendationIds: PropTypes.func.isRequired,
onConditionChange: PropTypes.func.isRequired,
conditions: PropTypes.array.isRequired,
collectionName: PropTypes.string.isRequired, // use params instead?
deletePoint: PropTypes.func.isRequired,
payloadSchema: PropTypes.object.isRequired,
};

export default PointCard;
16 changes: 13 additions & 3 deletions src/components/Points/PointVectors.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import { bigIntJSON } from '../../common/bigIntJSON';
/**
* Component for displaying vectors of a point
* @param {Object} point
* @param {function} onConditionChange
* @returns {JSX.Element|null}
* @constructor
*/
const Vectors = memo(function Vectors({ point, setRecommendationIds }) {
const Vectors = memo(function Vectors({ point, onConditionChange }) {
if (!Object.getOwnPropertyDescriptor(point, 'vector')) {
return null;
}
Expand Down Expand Up @@ -67,7 +68,16 @@ const Vectors = memo(function Vectors({ point, setRecommendationIds }) {
size="small"
variant="outlined"
onClick={() => {
setRecommendationIds([point.id], key === '' ? null : key);
onConditionChange(
[
{
key: 'id',
type: 'id',
value: point.id,
},
],
key === '' ? null : key
);
}}
>
Find Similar
Expand All @@ -82,7 +92,7 @@ const Vectors = memo(function Vectors({ point, setRecommendationIds }) {

Vectors.propTypes = {
point: PropTypes.object.isRequired,
setRecommendationIds: PropTypes.func.isRequired,
onConditionChange: PropTypes.func.isRequired,
};

export default Vectors;
Loading

0 comments on commit 6afc89f

Please sign in to comment.