Skip to content

Commit 79d0a26

Browse files
committed
feat(compass-crud): add 'Add to query' to the element context menu
1 parent 4af9c82 commit 79d0a26

File tree

6 files changed

+78
-4
lines changed

6 files changed

+78
-4
lines changed

packages/compass-components/src/components/document-list/document.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,14 @@ const HadronDocument: React.FunctionComponent<{
8686
editing?: boolean;
8787
onEditStart?: () => void;
8888
extraGutterWidth?: number;
89+
onAddToQuery?: (field: string, value: any) => void;
8990
}> = ({
9091
value: document,
9192
editable = false,
9293
editing = false,
9394
onEditStart,
9495
extraGutterWidth,
96+
onAddToQuery,
9597
}) => {
9698
const { elements, visibleElements } = useHadronDocument(document);
9799
const [autoFocus, setAutoFocus] = useState<{
@@ -156,6 +158,7 @@ const HadronDocument: React.FunctionComponent<{
156158
});
157159
}}
158160
extraGutterWidth={extraGutterWidth}
161+
onAddToQuery={onAddToQuery}
159162
></HadronElement>
160163
);
161164
})}

packages/compass-components/src/components/document-list/element.spec.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ describe('HadronElement', function () {
3434
editingEnabled={true}
3535
lineNumberSize={1}
3636
onAddElement={() => {}}
37+
onAddToQuery={() => {}}
3738
/>
3839
);
3940

@@ -59,6 +60,7 @@ describe('HadronElement', function () {
5960
editingEnabled={true}
6061
lineNumberSize={1}
6162
onAddElement={() => {}}
63+
onAddToQuery={() => {}}
6264
/>
6365
);
6466

@@ -82,6 +84,7 @@ describe('HadronElement', function () {
8284
editingEnabled={true}
8385
lineNumberSize={1}
8486
onAddElement={() => {}}
87+
onAddToQuery={() => {}}
8588
/>
8689
);
8790

@@ -107,6 +110,7 @@ describe('HadronElement', function () {
107110
editingEnabled={true}
108111
lineNumberSize={1}
109112
onAddElement={() => {}}
113+
onAddToQuery={() => {}}
110114
/>
111115
);
112116

@@ -117,5 +121,33 @@ describe('HadronElement', function () {
117121
// Check that the menu item doesn't exist
118122
expect(screen.queryByText('Open URL in browser')).to.not.exist;
119123
});
124+
125+
it('calls the correct parameters when "Add to query" is clicked', function () {
126+
const onAddToQuerySpy = sinon.spy();
127+
128+
render(
129+
<HadronElement
130+
value={element}
131+
editable={true}
132+
editingEnabled={true}
133+
lineNumberSize={1}
134+
onAddElement={() => {}}
135+
onAddToQuery={onAddToQuerySpy}
136+
/>
137+
);
138+
139+
// Open context menu and click the add to query option
140+
const elementNode = screen.getByTestId('hadron-document-element');
141+
userEvent.click(elementNode, { button: 2 });
142+
userEvent.click(screen.getByText('Add to query'), undefined, {
143+
skipPointerEventsCheck: true,
144+
});
145+
146+
// Verify that onAddToQuery was called with the field name and element's generated object
147+
expect(onAddToQuerySpy).to.have.been.calledWith(
148+
'field',
149+
element.generateObject()
150+
);
151+
});
120152
});
121153
});

packages/compass-components/src/components/document-list/element.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ export const HadronElement: React.FunctionComponent<{
428428
lineNumberSize: number;
429429
onAddElement(el: HadronElementType): void;
430430
extraGutterWidth?: number;
431+
onAddToQuery: (field: string, value: any) => void;
431432
}> = ({
432433
value: element,
433434
editable,
@@ -436,9 +437,11 @@ export const HadronElement: React.FunctionComponent<{
436437
lineNumberSize,
437438
onAddElement,
438439
extraGutterWidth = 0,
440+
onAddToQuery,
439441
}) => {
440442
const darkMode = useDarkMode();
441443
const autoFocus = useAutoFocusContext();
444+
442445
const {
443446
id,
444447
key,
@@ -461,6 +464,12 @@ export const HadronElement: React.FunctionComponent<{
461464
// Add context menu hook for the field
462465
const fieldContextMenuRef = useContextMenuItems(
463466
() => [
467+
{
468+
label: 'Add to query',
469+
onAction: () => {
470+
onAddToQuery(key.value, element.generateObject());
471+
},
472+
},
464473
{
465474
label: 'Copy field & value',
466475
onAction: () => {
@@ -480,7 +489,7 @@ export const HadronElement: React.FunctionComponent<{
480489
]
481490
: []),
482491
],
483-
[element, key.value, value.originalValue, value.value, type.value]
492+
[element, key.value, value.value, type.value, onAddToQuery]
484493
);
485494

486495
const toggleExpanded = () => {
@@ -770,6 +779,7 @@ export const HadronElement: React.FunctionComponent<{
770779
lineNumberSize={lineNumberSize}
771780
onAddElement={onAddElement}
772781
extraGutterWidth={extraGutterWidth}
782+
onAddToQuery={onAddToQuery}
773783
></HadronElement>
774784
);
775785
})}

packages/compass-crud/src/components/document.tsx

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import React, { useMemo } from 'react';
1+
import React, { useMemo, useCallback } from 'react';
22
import PropTypes from 'prop-types';
33
import HadronDocument from 'hadron-document';
44
import type { EditableDocumentProps } from './editable-document';
55
import EditableDocument from './editable-document';
66
import type { ReadonlyDocumentProps } from './readonly-document';
77
import ReadonlyDocument from './readonly-document';
88
import type { BSONObject } from '../stores/crud-store';
9+
import { useChangeQueryBarQuery } from '@mongodb-js/compass-query-bar';
910

1011
export type DocumentProps = {
1112
doc: HadronDocument | BSONObject;
@@ -32,6 +33,20 @@ const Document = (props: DocumentProps) => {
3233
return new HadronDocument(_doc as any);
3334
}, [_doc]);
3435

36+
const changeQuery = useChangeQueryBarQuery();
37+
38+
const onAddToQuery = useCallback(
39+
(field: string, value: any) => {
40+
if (changeQuery) {
41+
changeQuery('setValue', {
42+
field,
43+
value,
44+
});
45+
}
46+
},
47+
[changeQuery]
48+
);
49+
3550
if (editable && isTimeSeries) {
3651
return (
3752
<ReadonlyDocument
@@ -40,15 +55,24 @@ const Document = (props: DocumentProps) => {
4055
openInsertDocumentDialog={(doc, cloned) => {
4156
void openInsertDocumentDialog?.(doc, cloned);
4257
}}
58+
onAddToQuery={onAddToQuery}
4359
/>
4460
);
4561
}
4662

4763
if (editable) {
48-
return <EditableDocument {...props} doc={doc} />;
64+
return (
65+
<EditableDocument {...props} doc={doc} onAddToQuery={onAddToQuery} />
66+
);
4967
}
5068

51-
return <ReadonlyDocument doc={doc} copyToClipboard={copyToClipboard} />;
69+
return (
70+
<ReadonlyDocument
71+
doc={doc}
72+
copyToClipboard={copyToClipboard}
73+
onAddToQuery={onAddToQuery}
74+
/>
75+
);
5276
};
5377

5478
Document.propTypes = {

packages/compass-crud/src/components/editable-document.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type EditableDocumentProps = {
2121
openInsertDocumentDialog?: CrudActions['openInsertDocumentDialog'];
2222
copyToClipboard?: CrudActions['copyToClipboard'];
2323
showInsights?: boolean;
24+
onAddToQuery?: (field: string, value: any) => void;
2425
};
2526

2627
type EditableDocumentState = {
@@ -250,6 +251,7 @@ class EditableDocument extends React.Component<
250251
editable
251252
editing={this.state.editing}
252253
onEditStart={this.handleStartEditing.bind(this)}
254+
onAddToQuery={this.props.onAddToQuery}
253255
/>
254256
);
255257
}
@@ -315,6 +317,7 @@ class EditableDocument extends React.Component<
315317
openInsertDocumentDialog: PropTypes.func.isRequired,
316318
copyToClipboard: PropTypes.func.isRequired,
317319
showInsights: PropTypes.bool,
320+
onAddToQuery: PropTypes.func,
318321
};
319322
}
320323

packages/compass-crud/src/components/readonly-document.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export type ReadonlyDocumentProps = {
2929
openInsertDocumentDialog?: (doc: BSONObject, cloned: boolean) => void;
3030
doc: Document;
3131
showInsights?: boolean;
32+
onAddToQuery?: (field: string, value: any) => void;
3233
};
3334

3435
type ReadonlyDocumentState = {
@@ -183,6 +184,7 @@ class ReadonlyDocument extends React.Component<
183184
doc: PropTypes.object.isRequired,
184185
openInsertDocumentDialog: PropTypes.func,
185186
showInsights: PropTypes.bool,
187+
onAddToQuery: PropTypes.func,
186188
};
187189
}
188190

0 commit comments

Comments
 (0)