Skip to content

Commit 6e5f065

Browse files
authored
MONGOSH-210: Preserve compass-shell state when collapsing (#240)
1 parent d93d7e9 commit 6e5f065

File tree

10 files changed

+209
-91
lines changed

10 files changed

+209
-91
lines changed

packages/browser-repl/src/components/editor.spec.tsx

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,22 @@ describe('<Editor />', () => {
1111
return aceEditor.instance().editor as any;
1212
};
1313

14-
const execCommandBoundTo = (aceEditor: any, key: string): void => {
14+
const execCommandBoundTo = (
15+
aceEditor: any,
16+
key: { win: string; mac: string }
17+
): void => {
1518
const commands = Object.values(aceEditor.commands.commands);
16-
const command: any = commands.find(({ bindKey }) => {
19+
const command: any = commands.find(({ name, bindKey }) => {
1720
if (!bindKey) {
1821
return false;
1922
}
20-
21-
if (typeof bindKey === 'string') {
22-
return key === bindKey;
23+
if (name === 'gotoline') {
24+
// Ignore gotoline - our command overrides.
25+
return false;
2326
}
2427

25-
const { win, mac } = bindKey as {win: string; mac: string};
26-
return win === key && mac === key;
28+
const { win, mac } = bindKey as { win: string; mac: string };
29+
return win === key.win && mac === key.mac;
2730
});
2831

2932
if (!command) {
@@ -58,7 +61,24 @@ describe('<Editor />', () => {
5861
const aceEditor = getAceEditorInstance(wrapper);
5962
expect(spy).not.to.have.been.called;
6063

61-
execCommandBoundTo(aceEditor, 'Return');
64+
execCommandBoundTo(aceEditor, {
65+
win: 'Return',
66+
mac: 'Return'
67+
});
68+
expect(spy).to.have.been.calledOnce;
69+
});
70+
71+
it('calls onClearCommand when command/ctrl+L is pressed', () => {
72+
const spy = sinon.spy();
73+
const wrapper = mount(<Editor onClearCommand={spy} />);
74+
75+
const aceEditor = getAceEditorInstance(wrapper);
76+
77+
expect(spy).not.to.have.been.called;
78+
execCommandBoundTo(aceEditor, {
79+
win: 'Ctrl-L',
80+
mac: 'Command-L'
81+
});
6282
expect(spy).to.have.been.calledOnce;
6383
});
6484

@@ -69,7 +89,10 @@ describe('<Editor />', () => {
6989
const aceEditor = getAceEditorInstance(wrapper);
7090

7191
expect(spy).not.to.have.been.called;
72-
execCommandBoundTo(aceEditor, 'Up');
92+
execCommandBoundTo(aceEditor, {
93+
win: 'Up',
94+
mac: 'Up'
95+
});
7396
expect(spy).to.have.been.calledOnce;
7497
});
7598

@@ -82,7 +105,10 @@ describe('<Editor />', () => {
82105
aceEditor.moveCursorToPosition({ row: 1, column: 0 });
83106
aceEditor.clearSelection();
84107

85-
execCommandBoundTo(aceEditor, 'Up');
108+
execCommandBoundTo(aceEditor, {
109+
win: 'Up',
110+
mac: 'Up'
111+
});
86112
expect(spy).not.to.have.been.called;
87113
});
88114

@@ -96,7 +122,10 @@ describe('<Editor />', () => {
96122
aceEditor.clearSelection();
97123

98124
expect(spy).not.to.have.been.called;
99-
execCommandBoundTo(aceEditor, 'Down');
125+
execCommandBoundTo(aceEditor, {
126+
win: 'Down',
127+
mac: 'Down'
128+
});
100129
expect(spy).to.have.been.calledOnce;
101130
});
102131

@@ -107,7 +136,10 @@ describe('<Editor />', () => {
107136
const aceEditor = getAceEditorInstance(wrapper);
108137
aceEditor.setValue('row 0\nrow 1');
109138

110-
execCommandBoundTo(aceEditor, 'Down');
139+
execCommandBoundTo(aceEditor, {
140+
win: 'Down',
141+
mac: 'Down'
142+
});
111143
expect(spy).not.to.have.been.called;
112144
});
113145

@@ -119,7 +151,10 @@ describe('<Editor />', () => {
119151
aceEditor.setValue('text');
120152
aceEditor.selectAll();
121153

122-
execCommandBoundTo(aceEditor, 'Up');
154+
execCommandBoundTo(aceEditor, {
155+
win: 'Up',
156+
mac: 'Up'
157+
});
123158
expect(spy).not.to.have.been.called;
124159
});
125160

@@ -131,7 +166,10 @@ describe('<Editor />', () => {
131166
aceEditor.setValue('text');
132167
aceEditor.selectAll();
133168

134-
execCommandBoundTo(aceEditor, 'Down');
169+
execCommandBoundTo(aceEditor, {
170+
win: 'Down',
171+
mac: 'Down'
172+
});
135173
expect(spy).not.to.have.been.called;
136174
});
137175

packages/browser-repl/src/components/editor.tsx

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { Component } from 'react';
2-
import PropTypes from 'prop-types';
32
import AceEditor from 'react-ace';
43
import { Autocompleter } from '@mongosh/browser-runtime-core';
54
import { AceAutocompleterAdapter } from './ace-autocompleter-adapter';
@@ -11,35 +10,26 @@ import './ace-theme';
1110
import ace from 'brace';
1211
const tools = ace.acequire('ace/ext/language_tools');
1312

14-
const noop = (): void => {
15-
//
16-
};
13+
const noop = (): void => {};
1714

1815
interface EditorProps {
1916
onEnter?(): void | Promise<void>;
2017
onArrowUpOnFirstLine?(): void | Promise<void>;
2118
onArrowDownOnLastLine?(): void | Promise<void>;
2219
onChange?(value: string): void | Promise<void>;
20+
onClearCommand?(): void | Promise<void>;
2321
autocompleter?: Autocompleter;
2422
setInputRef?(ref): void;
2523
value?: string;
2624
}
2725

2826
export class Editor extends Component<EditorProps> {
29-
static propTypes = {
30-
onEnter: PropTypes.func,
31-
onArrowUpOnFirstLine: PropTypes.func,
32-
onArrowDownOnLastLine: PropTypes.func,
33-
onChange: PropTypes.func,
34-
setInputRef: PropTypes.func,
35-
value: PropTypes.string
36-
};
37-
3827
static defaultProps = {
3928
onEnter: noop,
4029
onArrowUpOnFirstLine: noop,
4130
onArrowDownOnLastLine: noop,
4231
onChange: noop,
32+
onClearCommand: noop,
4333
value: ''
4434
};
4535

@@ -60,6 +50,8 @@ export class Editor extends Component<EditorProps> {
6050
};
6151

6252
render(): JSX.Element {
53+
const { onClearCommand } = this.props;
54+
6355
return (<AceEditor
6456
showPrintMargin={false}
6557
showGutter={false}
@@ -114,6 +106,11 @@ export class Editor extends Component<EditorProps> {
114106

115107
this.props.onArrowDownOnLastLine();
116108
}
109+
},
110+
{
111+
name: 'clearShell',
112+
bindKey: { win: 'Ctrl-L', mac: 'Command-L' },
113+
exec: onClearCommand
117114
}
118115
]}
119116
width="100%"

packages/browser-repl/src/components/shell-input.tsx

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { Component } from 'react';
2-
import PropTypes from 'prop-types';
32
import classnames from 'classnames';
43
import { Editor } from './editor';
54
import { Autocompleter } from '@mongosh/browser-runtime-core';
@@ -9,9 +8,10 @@ import Icon from '@leafygreen-ui/icon';
98
const styles = require('./shell-input.less');
109

1110
interface ShellInputProps {
12-
onInput?(code: string): void | Promise<void>;
13-
history?: readonly string[];
1411
autocompleter?: Autocompleter;
12+
history?: readonly string[];
13+
onClearCommand?(): void | Promise<void>;
14+
onInput?(code: string): void | Promise<void>;
1515
setInputRef?(ref): void;
1616
}
1717

@@ -20,13 +20,6 @@ interface ShellInputState {
2020
}
2121

2222
export class ShellInput extends Component<ShellInputProps, ShellInputState> {
23-
static propTypes = {
24-
onInput: PropTypes.func,
25-
history: PropTypes.arrayOf(PropTypes.string),
26-
autocompleter: PropTypes.object,
27-
setInputRef: PropTypes.func
28-
};
29-
3023
readonly state: ShellInputState = {
3124
currentValue: ''
3225
};
@@ -116,13 +109,14 @@ export class ShellInput extends Component<ShellInputProps, ShellInputState> {
116109
/>);
117110

118111
const editor = (<Editor
119-
value={this.state.currentValue}
120-
onChange={this.onChange}
121-
onEnter={this.onEnter}
112+
autocompleter={this.props.autocompleter}
122113
onArrowUpOnFirstLine={this.historyBack}
123114
onArrowDownOnLastLine={this.historyNext}
124-
autocompleter={this.props.autocompleter}
115+
onChange={this.onChange}
116+
onEnter={this.onEnter}
117+
onClearCommand={this.props.onClearCommand}
125118
setInputRef={this.props.setInputRef}
119+
value={this.state.currentValue}
126120
/>);
127121

128122
const className = classnames(styles['shell-input']);

packages/browser-repl/src/components/shell.tsx

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { Component } from 'react';
2-
import PropTypes from 'prop-types';
32
import classnames from 'classnames';
43
import { ShellInput } from './shell-input';
54
import { ShellOutput, ShellOutputEntry } from './shell-output';
@@ -72,22 +71,6 @@ const noop = (): void => {
7271
* The browser-repl Shell component
7372
*/
7473
export class Shell extends Component<ShellProps, ShellState> {
75-
static propTypes = {
76-
runtime: PropTypes.shape({
77-
evaluate: PropTypes.func.isRequired
78-
}).isRequired,
79-
onOutputChanged: PropTypes.func,
80-
onHistoryChanged: PropTypes.func,
81-
redactInfo: PropTypes.bool,
82-
maxOutputLength: PropTypes.number,
83-
maxHistoryLength: PropTypes.number,
84-
initialOutput: PropTypes.arrayOf(PropTypes.shape({
85-
format: PropTypes.string.isRequired,
86-
value: PropTypes.any.isRequired
87-
})),
88-
initialHistory: PropTypes.arrayOf(PropTypes.string)
89-
};
90-
9174
static defaultProps = {
9275
onHistoryChanged: noop,
9376
onOutputChanged: noop,
@@ -162,6 +145,15 @@ export class Shell extends Component<ShellProps, ShellState> {
162145
return output;
163146
}
164147

148+
private onClearCommand = (): void => {
149+
const output = [];
150+
151+
Object.freeze(output);
152+
153+
this.setState({ output });
154+
this.props.onOutputChanged(output);
155+
};
156+
165157
private onInput = async(code: string): Promise<void> => {
166158
const inputLine: ShellOutputEntry = {
167159
format: 'input',
@@ -212,6 +204,7 @@ export class Shell extends Component<ShellProps, ShellState> {
212204
</div>
213205
<div ref={(el): void => { this.shellInputElement = el; }}>
214206
<ShellInput
207+
onClearCommand={this.onClearCommand}
215208
onInput={this.onInput}
216209
history={this.state.history}
217210
autocompleter={this.props.runtime}

packages/cli-repl/src/completer.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ const BASE_COMPLETIONS = EXPRESSION_OPERATORS.concat(
1616

1717
const MATCH_COMPLETIONS = QUERY_OPERATORS.concat(BSON_TYPES);
1818

19-
const SHELL_COMPLETIONS = shellSignatures.ShellApi.attributes;
20-
const COLL_COMPLETIONS = shellSignatures.Collection.attributes;
21-
const DB_COMPLETIONS = shellSignatures.Database.attributes;
22-
const AGG_CURSOR_COMPLETIONS = shellSignatures.AggregationCursor.attributes;
23-
const COLL_CURSOR_COMPLETIONS = shellSignatures.Cursor.attributes;
24-
const RS_COMPLETIONS = shellSignatures.ReplicaSet.attributes;
25-
const SHARD_COMPLETE = shellSignatures.Shard.attributes;
26-
2719
/**
2820
* The proect stage operator.
2921
*/
@@ -42,6 +34,14 @@ const GROUP = '$group';
4234
* @returns {array} Matching Completions, Current User Input.
4335
*/
4436
function completer(mdbVersion: string, line: string): [string[], string] {
37+
const SHELL_COMPLETIONS = shellSignatures.ShellApi.attributes;
38+
const COLL_COMPLETIONS = shellSignatures.Collection.attributes;
39+
const DB_COMPLETIONS = shellSignatures.Database.attributes;
40+
const AGG_CURSOR_COMPLETIONS = shellSignatures.AggregationCursor.attributes;
41+
const COLL_CURSOR_COMPLETIONS = shellSignatures.Cursor.attributes;
42+
const RS_COMPLETIONS = shellSignatures.ReplicaSet.attributes;
43+
const SHARD_COMPLETE = shellSignatures.Shard.attributes;
44+
4545
// keep initial line param intact to always return in return statement
4646
// check for contents of line with:
4747
const splitLine = line.split('.');

0 commit comments

Comments
 (0)