Skip to content

Conversation

@gagik
Copy link
Contributor

@gagik gagik commented Jul 3, 2025

Adds an "Add to query" and "Remove to query" for adding and removing conditions from query with right click
Screenshot 2025-07-07 at 1 09 54 PM
Screenshot 2025-07-07 at 1 10 19 PM

@gagik gagik changed the title feat(compass-crud): add 'Add to query' to the element context menu feat(compass-crud): add 'Add to query' to the element context menu COMPASS-9394 Jul 3, 2025
{
label: 'Add to query',
onAction: () => {
onAddToQuery(key.value, element.generateObject());
Copy link
Collaborator

@gribnoysup gribnoysup Jul 4, 2025

Choose a reason for hiding this comment

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

Not sure that for nested queries it works as expected, this filter I got for one of the genres item is kinda not meaningful (same for nested objects):

image

We probably want to build the whole key when adding something to the filter, similar to how schema visualizer does it:

image

@gagik gagik force-pushed the gagik/add-to-query-menu branch from 63660e1 to b0d3c3f Compare July 4, 2025 14:04
* Helper function to get the nested key path of an element, skips array keys
* Meant for keypaths used in query conditions from a selected element
*/
const getNestedKeyPath = (element: HadronElementType): string => {
Copy link
Contributor Author

@gagik gagik Jul 4, 2025

Choose a reason for hiding this comment

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

Not sure if this fully replicates what was meant with schema visualization but this approach seems to work, the only caveat here is that with arrays one can only add to query 1 nested item at a time.
Alternatively we can make it specify the index (which would enforce its position.... not sure how common that is) or manually handle it to be smarter about it.

IMO, as a first iteration one item a time isn't too bad. We can have multiple nested fields for the object in the meantime so that's good

Copy link
Collaborator

Choose a reason for hiding this comment

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

We already handle this in schema tab with toggleDistinctValue case (or as we only have "add" here, you can look at addDistinctValue), I think for an "add to query" option it makes more sense than overriding the existing value

[changeQuery]
);

const isInQuery = useCallback(
Copy link
Contributor Author

@gagik gagik Jul 7, 2025

Choose a reason for hiding this comment

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

@gribnoysup toggling seems to work pretty well so I changed the experience to also let us remove from query accordingly.

The only corner case I noticed is trying to add to query the whole array (i.e. without expanding) and then trying to add a specific element. This seems like something that'd need to be handled differently at toggleDistinctValue level I'd guess?

Not sure if the prop passing here is getting too much. I was thinking of at least combining them into a single queryController (or better naming...) object that would have add and contains to combine these 2 callbacks.

Comment on lines 44 to 57
const queryBar = useMemo<QueryBarController>(() => {
return {
isInQuery: (field: string, value: unknown) => {
const filter = queryBarQuery.filter?.[field];
return hasDistinctValue(filter, value);
},
toggleQueryFilter: (field: string, value: unknown) => {
queryBarChangeQuery('toggleDistinctValue', {
field,
value,
});
},
};
}, [queryBarChangeQuery, queryBarQuery]);
Copy link
Collaborator

@gribnoysup gribnoysup Jul 7, 2025

Choose a reason for hiding this comment

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

Feel free to tell me "no" on this, but I think we might want to stick with more common React patterns here, at least I don't see much reason for this controller interface over just props (but again, I'm not strongly against what you have here), I think in the long run it might make it tough to connect the dots in the code. Some thoughts in no particular order:

  • Usually passing down a getter like isInQuery that you have here is done for control flow inversion purposes (that usually related to some tricky rendering flows) where the child has more control over rendering that you don't have (like getItemIndex in react-window for example). As we're not doing anything like that here I think you might as well just pass the whole query to the document and calculate the isInQuery value in the Element render instead.
  • If you do want to optimize this (which is maybe not a bad idea so that we don't re-render the whole document list while user types a query), you will need to go a different way about this, the function here needs to be completely stable for this to work, so some sort of query ref instead of query state will be needed. But that's also maybe a reason to just do "add to query" for the moment and avoid complicating this too much.
  • The toggleQueryFilter is really just a normal callback prop, so I'd suggest to stick with it and make it into optional onUpdateQueryClick (or something similar) prop directly on the component, I think that's what you had before here and it honestly makes a lot of sense as an interface

Copy link
Contributor Author

@gagik gagik Jul 8, 2025

Choose a reason for hiding this comment

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

agreed all around, I'm still going to keep Remove query wherever possible since I'd have to handle the "toggle" logic one way or another or introduce a new add-only action to the change to query helper function. I think as it stands the removal is quite useful and works well enough

@gagik gagik force-pushed the gagik/add-to-query-menu branch from ca63796 to a616886 Compare July 8, 2025 10:10
@gagik gagik marked this pull request as ready for review July 8, 2025 11:30
@gagik gagik requested a review from a team as a code owner July 8, 2025 11:30
} = useHadronElement(element);

// Function to check if a field is in the query
// TODO: COMPASS-9541 Improve the functionality when checking for nested objects.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

export const hasDistinctValue = (
field: { $in: any } | undefined,
value?: any
field: Record<string, unknown> | undefined,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

drive-by fix as the types didn't seem right

@gagik gagik changed the title feat(compass-crud): add 'Add to query' to the element context menu COMPASS-9394 feat(compass-crud): add 'Add to query' to the element context menu COMPASS-9394 Jul 8, 2025
@github-actions github-actions bot added the feat label Jul 8, 2025
@gagik gagik added the no release notes Fix or feature not for release notes label Jul 8, 2025
@gagik gagik requested a review from mabaasit July 9, 2025 07:51
@mabaasit
Copy link
Collaborator

mabaasit commented Jul 9, 2025

Looks good, however I noticed one more issue when adding query. I've attached video

Screen.Recording.2025-07-09.at.11.32.56.mov

@mabaasit
Copy link
Collaborator

mabaasit commented Jul 9, 2025

Looks good, however I noticed one more issue when adding query. I've attached video

Screen.Recording.2025-07-09.at.11.32.56.mov

Okay, we have a follow up on this specific issue: COMPASS-9541.

@gagik
Copy link
Contributor Author

gagik commented Jul 10, 2025

Product confirmed the edge cases are minor and we can follow up on this behavior with COMPASS-9541, going ahead with merge.

@gagik gagik merged commit e49efac into main Jul 10, 2025
59 checks passed
@gagik gagik deleted the gagik/add-to-query-menu branch July 10, 2025 07:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat no release notes Fix or feature not for release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants